Q:

Can gmock be used for stubbing C functions?

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)
{
  boolean find;
  // Some code
  find = func_1();
  return find;
}

I have searched about gmock and in my understanding gmock does not provide functionality to stub simple C functions, therefore I want to ask does gmock provides functionality to mock or stub func_1?
If not how can I stub func_1 manually in my test code without changing source code? I am using google test framework for unit testing.
Thanks.

A:

I found myself in the same situation lately. I had to write unit tests for
libraries written in C, which in turn had dependencies to other libraries also written in C. So I wanted to mock all function calls of dependencies
using gmock. Let me explain my approach by an example.
Assume the code to be tested (library A) calls a function from another library, lib_x_function():
lib_a_function()
{
   ...
   retval = lib_x_function();
   ...
}

So, I want to mock the library X. Therefore I write an interface class and a
mock class in a file lib_x_mock.h:
class LibXInterface {
public:
   virtual ~LibXInterface() {}
   virtual int lib_x_function() = 0;
}

class LibXMock : public LibXInterface {
public:
   virtual ~LibXMock() {}
   MOCK_METHOD0(lib_x_function, int());
}

Additionally I create a source file (say, lib_x_mock.cc), that defines a stub
for the actual C function. This shall call the mock method. Note the extern
reference to the mock object.
#include lib_x.h
#include lib_x_mock.h
extern LibXMock LibXMockObj;    /* This is just a declaration! The actual
                                   mock obj must be defined globally in your
                                   test file. */

int lib_x_function()
{
    return LibXMockObj.lib_x_function();
}

Now, in the test file, which tests the library A, I must define the mock object
globally, so that it is both reachable within your tests and from
lib_x_mock.cc. This is lib_a_tests.cc:
#include lib_x_mock.h

LibXMock LibXMockObj;  /* This is now the actual definition of the mock obj */

...
TEST_F(foo, bar)
{
   EXPECT_CALL(LibXMockObj, lib_x_function());
   ...
}

This approach works perfectly for me, and I have dozens of tests and several
mocked libraries. However, I have a few doubts if it is ok to create a
global mock object - I asked this in a separate question and still wait for answers. Besides this I'm happy with the solution.

EDIT: The problem about the global object can be easily remedied by creating the object e.g. in the constructor of the test fixture, and just storing a pointer to that object in a global variable.
However, also note my alternative answer to this question, that I just posted.

A:

This is another answer of mine to this question. In the two years that passed since the first answer, I came to understand that GMock is simply the wrong framework for mocking C functions. In situations where you have a lot of functions to mock, my previously posted answer is simply too cumbersome. The reason is that GMock uses Object Seams to replace production code with mock code. This relies on polymorphic classes, which don't exist in C.
Instead, to mock C functions, you should use Link Seams, which replace the production code with the mock code at link time. Several frameworks exist for this purpose, but my favorite one is the Fake Function Framework (FFF). Check it out, it's a lot simpler than GMock. It also works perfectly well in C++ applications.
For the interested, here is a good article by Michael Feathers about the different seam types.

A:

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 <memory>
#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<BCM2835Lib_MOCK>());
    }
    ~TestFixture(){
        _bcm2835libMock.reset();
    }
    virtual void SetUp(){}
    virtual void TearDown(){}

    // pointer for accessing mocked library
    static std::unique_ptr<BCM2835Lib_MOCK> _bcm2835libMock;
};

Instantiate mocked lib functions
// instantiate mocked lib
std::unique_ptr<BCM2835Lib_MOCK> 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.

