Mocking External Dependency object created inside a function without dependency injection in c++

1.2k Views Asked by At

I am trying to write unit tests in C++ and am facing an issue with creating mock objects for an external dependency using Fakeit. So we have a class similar to the following:

class A 
{
    int test_method()
    {
        B obj;
        return obj.sendInt()
    }
};

class B
{
    int sendInt()
    {
        return 5;
    }
};

Now let's say I want to write a unit test for test_method() of class A. When we call obj.sendInt() I want to mock it and return a different value. I tried using fakeit but was not able to arrive at a solution.

I know this will be solved if we try to do a dependency injection of B via constructor or in setter methods, but I don't want to do it as it would take some refactoring in existing consumers of A.

For a similar scenario in Java, I would use PowerMockito and achieve the same using PowerMockito.whenNew

B mock = Mockito.mock(B.class);
PowerMockito.whenNew(B.class).withAnyArguments().thenReturn(mock);
Mockito.when(mock.test()).thenReturn(2);
A obj=new A();
assertEquals(obj.test(), 2);
2

There are 2 best solutions below

1
On

I moved the code which initializes B and invokes its method to a private method and mocked this private method using gmock

class A 
{

int test_method()
{
return getBValue();
}
int getBValue()
{
B obj;
return obj.sendInt()
}

}

My Test Method looks like,

Class MockA :: A
{
public:
MOCK_METHOD(int,getBValue,(),override);

}

TEST_CASE("Test1")
{
MockA mock;
ON_CALL(mock, getBValue()).WillByDefault(Return(10));
REQUIRE(mock.test_method()==10);
}
1
On

The easiest way would be to use dependency injection. I don't think there's anything similar to PowerMockito for C++ (e.g. it's impossible to mock static methods/functions in a similar manner as PowerMockito allows for java).

If the issue is only with the dependency injection via ctor or setter methods, consider using hi-perf dependency injection, i.e. inject mock using templates.

If the class A cannot be modified at all but you own the class B, consider moving class B to a separate static library: one for production (say, libBprod) and one for testing (libBtest). In production you can link against the libBprod and in tests against libBtest. In libBtest, you can make class B a singleton under the hood. This is quite a lot of work though.

If both class A and class B cannot be modified, then I'm out of ideas - you need to refactor some part of the code somehow.