Introduction to CppUTest Mocking

v0.5
CppUTest has support for building mocks. This document described the mocking support as was released in CppUTest 2.2. A couple of design goals for the mocking support were:
The main idea is to make manual mocking easier, rather than to make automated mocks. If manual mocking is easier, then it could also be automated in the future, but that isn't a goal by itself.

Simple scenario

About the simplest scenario is to check that one particular function call has happened. The below code is an example of this:
#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"

TEST_GROUP(MockDocumentation)
{
};


void productionCode()
{
    mock().actualCall("productionCode");
}

TEST(MockDocumentation, SimpleScenario)
{
    mock().expectOneCall("productionCode");
    productionCode();
    mock().checkExpectations();
}
The only additional include for mocking is CppUTestExt/MockSupport.h which is the main include for anything CppUTest Mocking. The declaration of the TEST_GROUP is the same as always, there is no difference.

The TEST(MockDocumentation, SimpleScenario) contains the recording of the expectations as:
    mock().expectOneCall("productionCode");
The call to mock() return the global MockSupport (more about that later) on which we can record our expectations. In this example, we'll call expectOneCall("productionCode") which... records an expectation for *one* call to a function called productionCode.

The productionCode call is to show a call to whatever your real code is. The test ends with checking whether the expectations have been met. This is done with the:
    mock().checkExpectations();
This call is needed when *not* using the MockSupportPlugin, otherwise this is done automatically for every single test.

The actual mocked function call looks like:
void productionCode()
{
    mock().actualCall("productionCode");
}
where we use MockSupport by calling mock() and then record the actual call to the productionCode function.

This scenarion is quite common when using linker stubbing of e.g. a 3rd partly library.

If the call to productionCode wouldn't happen, then the test would fail with the following error message:
ApplicationLib/MockDocumentationTest.cpp:41: error: Failure in TEST(MockDocumentation, SimpleScenario)
Mock Failure: Expected call did not happen.
    EXPECTED calls that did NOT happen:
        productionCode -> no parameters
    ACTUAL calls that did happen:
        <none>

Simple scenario using objects

There is no difference between mocking functions and objects. Below code shows a mock using run-time mocking:

class ClassFromProductionCodeMock : public ClassFromProductionCode
{
public:
virtual void importantFunction()
{
mock().actualCall("importantFunction");
}
};

TEST(MockDocumentation, SimpleScenarioObject)
{
mock().expectOneCall("importantFunction");

ClassFromProductionCode* object = new ClassFromProductionCodeMock; /* create mock instead of real thing */
object->importantFunction();
mock().checkExpectations();

delete object;
}
The code is self-explanatory. The real object is replaced by a hand-made mock object. The call to the mock then records the actual call via the MockSupport.

When using objects, we can also check whether the call was done on the right object, via this:
mock().expectOneCall("importantFunction").onObject(object);
and the actual call would then be:
mock().actualCall("importantFunction").onObject(this);
If the call to a wrong object happens, it would give the following error message:
    MockFailure: Function called on a unexpected object: importantFunction
    Actual object for call has address: <0x1001003e8>
    EXPECTED calls that DID NOT happen related to function: importantFunction
        (object address: 0x1001003e0)::importantFunction -> no parameters
    ACTUAL calls that DID happen related to function: importantFunction
        <none>

Using parameters

Of course, just checked whether a function is called is not particularly useful when we cannot check the parameters. Recording parameters on a function is done like this:
    mock().expectOneCall("function").onObject(object).withParameter("p1", 2).withParameter("p2", "hah");
And the actual call is like:
    mock().actualCall("function").onObject(this).withParameter("p1", p1).withParameter("p2", p2);
If a parameter isn't passed, it will give the following error:
    Mock Failure: Expected parameter for function "function" did not happen.
    EXPECTED calls that DID NOT happen related to function: function
        (object address: 0x1)::function -> int p1: <2>, char* p2: <hah>
    ACTUAL calls that DID happen related to function: function
        <none>
    MISSING parameters that didn't happen:
        int p1, char* p2

Objects as parameters

withParameters can only use int, double, const char* or void*. However, parameters are often objects of other types and not of the basic types. How to handle objects as paramaters? Below is an example:
    mock().expectOneCall("function").withParameterOfType("myType", "parameterName", object);
When using withParameterOfType, the mocking framework needs to know how to compare the type and therefore a Comparator has to be installed before using parameters of this type. This is done using installComparator, as below:
    MyTypeComparator comparator;
    mock().installComparator("myType", comparator);
MyTypeComparator is a customer comparator, which implements the MockNamedValueComparator interface. For example:

class MyTypeComparator : public MockNamedValueComparator
{
public:
    virtual bool isEqual(void* object1, void* object2)
    {
        return object1 == object2;
    }
    virtual SimpleString valueToString(void* object)
    {
        return StringFrom(object);
    }
};
The isEqual is called to compare the two parameters. The valueToString is called when an error message is printed and it needs to print the actual and expected values. If you want to use normal C functions, you can use the MockFunctionComparator which accepts pointers to functions in the constructor.

To remove the comparators, all you needs to do is call removeAllComparators, like:
    mock().removeAllComparators();
Comparators sometimes lead to surprised, so a couple of warnings on its usage:

Warning 1: Pay attention to the scope of your comparator variable!
    Comparators are *not* copied, instead it uses the exact instance as passed to the installComparator function. So make sure it is still in-scope when the framework tries to use it! For example, if you installComparator inside the TEST, but do the checkExpectations in the teardown, then it is likely to cause a crash since the comparator has been destroyed.

Warning 2: Pay extra attention to scope when using the MockPlugin
    When using the MockPlugin (recommended), then its best to install the comparators via the MockPlugin or put them in global space. The checkExpectations will be called *after* teardown and if your comparator was destroyed in the teardown then this will cause a crash.

Return values

Sometimes it is needed to let a mock function return a value which can then be used in production code. This can be done like:
    mock().expectOneCall("function").andReturnValue(10);
And it can be used in the actual call like:
    int value = mock().actualCall("function").returnValue().getIntValue();
or separate from the actualCall (below it!) like:
    value = mock().returnValue().getIntValue();
The return value options are used to transfer data between the test and the mock object, they themselves do not cause the tests to fail.

Passing other data

Sometimes a test wants to pass more data to the mock object to, for example, vary only a couple of parameters in a calculation. This can be done like this:
    ClassFromProductionCode object;
    mock().setData("importantValue", 10);
    mock().setDataObject("importantObject", "ClassFromProductionCode", &object);
And it can be used in the mock object like:
    ClassFromProductionCode * pobject;
    int value = mock().getData("importantValue").getIntValue();
    pobject = (ClassFromProductionCode*) mock().getData("importantObject").getObjectPointer();
Like return values. Setting data will not ever make a test fail but it provides support in building mock objects.

Other MockSupport - ignoring, enabling, clearing, crashing

MockSupport offers a couple of other useful functions, which will be covered in this section.

Frequently, you only want to check a couple of calls in your test and ignore all the other calls. If you add expectOneCall for each of these calls, you're tests might become too large (though, it might be a smell that your test is indeed too large). One way to prevent this is the ignoreOtherCalls, like:
    mock().expectOneCall("foo");
    mock().ignoreOtherCalls();
This will check that one call of foo happens (and only one call!), but all other calls will be ignored (such as "bar").

Sometimes, you don't want to just ignore calls, but instead disable the whole mocking framework for a while (too do *something*). This happens sometimes in initialization where you might want to do *something* without the mocking framework checking calls. You can do this by enabling/disabling such as:

    mock().disable();
    doSomethingThatWouldOtherwiseBlowUpTheMockingFramework();
    mock().enable();
If you want to clear all the expectations, settings, and comparators, call clear:
    mock().clear();
Clear won't do checkExpectations, but just erase everything and start over. Usually clear() is called after a checkExpectations.

Sometimes, a mock actual call happens, but you cannot figure out from where it is called. If you only had a call stack, then it you could track it. Well, unfortunately, the mocking framework doesn't print stack traces, but it can crash! If you call the crashOnFailure on the MockSupport, then it will crash so that you can use the debugger to get a stack trace. like:
    mock().crashOnFailure();
When using gdb, get a stack trace using:
    gdb examples/CppUTestExamples_tests
r
bt
(r is run, it will run until crashes. bt is back trace which will produce a stack)

MockSupport Scope

MockSupport can be used hierarchically using MockSupport scope. This sounds really complex, but in reality it is very simple. When getting a mock support using the mock function, you can pass a namespace or scope and record the expectations (or do other things) inside this scope. For example:
    mock("xmlparser").expectOneCall("open");
The actual call then has to look like this:
    mock("xmlparser").actualCall("open");
A call on another namespace won't work, for example this won't match the call to xmlparser open:
    mock("").actualCall("open");
Keeping calls in namespaces makes it easy to ignore one type of call and focus on another, for example:
    mock("xmlparser").expectOneCall("open");
    mock("filesystem").ignoreOtherCalls();

Less work with MockPlugin

CppUTest plugins can be installed in the main and 'extent' the unit test framework. It is a place where you can put work that needs to be done in all unit tests. There is a MockPlugin to make the work with mocks easier. It does the following work:
Installing the MockPlugin means you'll have to add to main something like:

    MyDummyComparator dummyComparator;
    MockSupportPlugin mockPlugin;

    mockPlugin.installComparator("MyDummyType", dummyComparator);
    TestRegistry::getCurrentRegistry()->installPlugin(&mockPlugin);
This code creates a comparator for MyDummy and installs it at the plugin. This means the comparator is available for all test cases. It creates the plugin and installs it at the current test registry. After installing the plugin, you don't have to worry too much anymore about calling checkExpectations or cleaning your MockSupport.

Working with the C interface

Sometimes it is useful to access the mocking framework from a .c file rather than a .cpp file. For example, perhaps, for some reason, the stubs are implemented in a .c file rather than a .cpp file. Instead of changing over all to .cpp, it would be easier if the mocking framework can be called via C. The C interface is exactly meant for this. The interface is based on the C++ one, so below is some code and it ought to be easy to figure out what it does (if you've read all that was written earlier):

    #include "CppUTestExt/MockSupport_c.h"

    mock_c()->expectOneCall("foo")->withIntParamaters("integer", 10)->andReturnDoubleValue(1.11);
    mock_c()->actualCall("foo")->withIntParamaters("integer", 10)->returnValue().value.doubleValue;

    mock_c()->installComparator("type", equalMethod, toStringMethod);
    mock_scope_c("scope")->expectOneCall("bar")->withParameterOfType("type", "name", object);
    mock_scope_c("scope")->actualCall("bar")->withParameterOfType("type", "name", object);
    mock_c()->removeAllComparators();

    mock_c()->setIntData("important", 10);

    mock_c()->checkExpectations();
    mock_c()->clear();

The C interface uses a similar builder structure as the C++ interface. It is far less common in C, but it works the same.

Feedback

Any feedback on this mocking framework is more than welcome, please mail me as basv AT odd-e.com.