Can gmock be used for stubbing C functions?

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.


UPDATE: 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.

Leave a Comment