C++ Unit Testing – How to Use Mock Objects Without Passing as Arguments

cmockingunit testing

I'm in the process of integrating a Unit Testing Framework for an existing code base in C++. I've zeroed down on CxxTest, but as it turns out we can use other Mocking Frameworks (like googlemock) in conjunction with CxxTest too.

After reading tutorials on CxxTest (Mocking) and googlemock (the infamous turtle example), I have the general idea that you have to define a mock class (using macros etc), declare an object of the mock class and then pass it to the function you are unit testing. Now, there are many occurences in the existing code base where it isn't possible to do that.

Here's an pseudo example to clarify:

class CCandidateForTest
{
    public:
    bool foo(int a)
    {
        CAnotherClass obj;
        int b = obj.bar(a+2);
        if (a == b) {
            return true;
        } else {
            return false;
        }
    }
}

(This is over-simplified, there are also exceptions and the primitive types may also be other objects etc.; but you get the general idea) (also, creation of objects is not always direct and may sometimes use a factory)

I want to write a test for the function CCandidateForTest::foo. This method internally creates an object of CAnotherClass, which I need to mock so that CAnotherClass::bar returns different values so that different code paths in foo are traversed in unit testing.

In a nutshell, the problem is that the function being tested internally creates an object of the class that needs to be mocked – hence passing an instance of the mocked object to the function is not possible.

How do I use mocking in such a case? Is there a specific mocking framework that makes this possible?

Best Answer

You could use a factory to create instances of CAnotherClass.

class CCandidateForTest
{
    public:
    bool foo(int a)
    {
        std::shared_ptr< CAnotherClassInterface > obj = CAnotherClassFactory::Create();
        int b = obj->bar(a+2);
        if (a == b) {
            return true;
        } else {
            return false;
        }
    }
}

CAnotherClassFactory can look like :

class CAnotherClassFactory
{
public:
    typedef std::shared_ptr< CAnotherClassInterface > (*fn)();
    static std::shared_ptr< CAnotherClassInterface > Create()
    {
        return createFn();
    }

    static fn createFn;
};

Random thoughts about your approach :

  • If that is over-simplified, then you need to think how to refactor it.
  • there are better unit test frameworks then cxxunit. gtest and cute-test.com