Can gmock be used for stubbing C functions?

前端 未结 6 1770
时光取名叫无心
时光取名叫无心 2020-12-05 15:25

I am new to gmock, so I want to know how can I stub simple C function called in a function under test for Unit Testing.

Example:

int func(int a)
{
           


        
6条回答
  •  暖寄归人
    2020-12-05 15:43

    I was looking already a long time for a solution to mock legacy c-functions with googleMock without changing existing code and last days I found the following really great article: https://www.codeproject.com/articles/1040972/using-googletest-and-googlemock-frameworks-for-emb

    Today I wrote my first unit test for c-functions using gmock and took as example two functions from the bcm2835.c library (http://www.airspayce.com/mikem/bcm2835/) for raspberry Pi programming: Here is my solution: I'm using the gcc 4.8.3. under Eclipse and Windows. Be Aware to set the Compiler option -std=gnu++11.

    Here are my functions to be tested

    int inits(void);
    void pinMode(uint8_t pin, uint8_t mode);
    
    int inits(){
        return bcm2835_init();
    }
    
    void pinMode(uint8_t pin, uint8_t mode){
        bcm2835_gpio_fsel(pin, mode);
    }
    

    Includes and defines for unit testing with googleTest / googleMock

    // MOCKING C-Functions with GMOCK :)
    #include 
    #include "gtest/gtest.h"
    #include "gmock/gmock.h"
    using namespace ::testing;
    using ::testing::Return;
    

    Mock BCM2835Lib functions

    class BCM2835Lib_MOCK{
    public:
        virtual ~BCM2835Lib_MOCK(){}
    
        // mock methods
        MOCK_METHOD0(bcm2835_init,int());
        MOCK_METHOD2(bcm2835_gpio_fsel,void(uint8_t,uint8_t));
    };
    

    Create a TestFixture

    class TestFixture: public ::testing::Test{
    public:
        TestFixture(){
            _bcm2835libMock.reset(new ::testing::NiceMock());
        }
        ~TestFixture(){
            _bcm2835libMock.reset();
        }
        virtual void SetUp(){}
        virtual void TearDown(){}
    
        // pointer for accessing mocked library
        static std::unique_ptr _bcm2835libMock;
    };
    

    Instantiate mocked lib functions

    // instantiate mocked lib
    std::unique_ptr TestFixture::_bcm2835libMock;
    

    Fake lib functions to connect Mocks with the c-functions

    // fake lib functions
    int  bcm2835_init(){return TestFixture::_bcm2835libMock->bcm2835_init();}
    void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode){TestFixture::_bcm2835libMock->bcm2835_gpio_fsel(pin,mode);}
    

    Create unit testing class for BCM2835 from TestFixture

    // create unit testing class for BCM2835 from TestFixture
    class BCM2835LibUnitTest : public TestFixture{
    public:
        BCM2835LibUnitTest(){
            // here you can put some initializations
        }
    };
    

    Write the Tests using googleTest and googleMock

    TEST_F(BCM2835LibUnitTest,inits){
        EXPECT_CALL(*_bcm2835libMock,bcm2835_init()).Times(1).WillOnce(Return(1));
    
        EXPECT_EQ(1,inits()) << "init must return 1";
    }
    
    TEST_F(BCM2835LibUnitTest,pinModeTest){
    
        EXPECT_CALL(*_bcm2835libMock,bcm2835_gpio_fsel( (uint8_t)RPI_V2_GPIO_P1_18
                                                       ,(uint8_t)BCM2835_GPIO_FSEL_OUTP
                                                      )
                   )
                   .Times(1)
                   ;
    
        pinMode((uint8_t)RPI_V2_GPIO_P1_18,(uint8_t)BCM2835_GPIO_FSEL_OUTP);
    }
    

    Results :)

    [----------] 2 tests from BCM2835LibUnitTest
    [ RUN      ] BCM2835LibUnitTest.inits
    [       OK ] BCM2835LibUnitTest.inits (0 ms)
    [ RUN      ] BCM2835LibUnitTest.pinModeTest
    [       OK ] BCM2835LibUnitTest.pinModeTest (0 ms)
    [----------] 2 tests from BCM2835LibUnitTest (0 ms total)
    

    Hope it will help :) - for me this is a really working solution.

提交回复
热议问题