Using googlemock with fake impls of non-virtual functions - c++

I've got legacy code with some unit tests based on googlemock framework. While I was trying to extend the unit tests with some new scenarios I met the following problem:
class D
{
public:
void pubMethod1();
int pubMethod2();
// There are pretty much non-virtual methods, both public and private
...
protected:
uint method3();
void method4();
...
// Some class members are here
};
class SUT
{
public:
...
protected:
D _dep;
};
The SUT class (software under test) should be tested, its implementation is defined in file sut.cpp. The SUT depends on D class, whose implementation is in file d.cpp. To decrease linker dependencies I would not like to add d.cpp to the test, so there are many 'undefined symbol' errors against the D's members when I link the test. To eleminate the errors and provide predictable behaviour I'm going to create fake implementations for the D's methods in my test. However I'm still not able to use it with all the googlemock's power until the D's methods are virtual.
I like an idea to use WillOnce, AtLeast, WillRepeatedly, Invoke, etc. functions from the googlemock framework, because it makes unit test creation easier. The problem is that I don't like an idea to change the D's interface, turning its methods into virtual ones. Is it possible to use the googlemock functions with the fake implementations I'm going to create for the D's methods?
NOTE: I already considered the solution with templated SUT class, however I'm wondering if other solution exists.

First of all - the best would be to redesign your SUT class to have D injected via some abstract interface. Because the workaround I am describing below is really tricky - so not so easy to maintain and understand in future...
If you are going to make fake implememtation of your D class in UT target - then you can make Mock class for D: DMock. This DMock will not be related to D - not derived from it - but it needs to be paired with real/fake D objects.
So - see the example:
Create DMock - that imitates the D interface (note that you should mock only public functions - because your SUT uses only public ones):
class DMock
{
public:
MOCK_METHOD0(pubMethod1, void ());
MOCK_METHOD0(pubMethod2, int ());
};
Pair your real (but fake) D objects with DMock objects - something like this:
class DMockRepo
{
public:
// for UT
void addMockToUse(DMock* dMock) { freeMock.push_back(dMock); }
// for implementing D fake methods
DMock& getMock(D* original)
{
// TODO: use more sophisticated way to add mock to map...
if (not usedMock[original])
{
usedMock[original] = freeMock.front();
freeMock.pop_front();
}
return *useddMock[original];
}
static DMockRepo& getInstance() { return instance; } //singleton
private:
DMockRepo() {} // private
static DMockRepo instance;
std::map<D*,DMock*> usedMock;
std::deque<DMock*> freeMock;
};
Use mock to create fake implementation of public methods of D class:
void D::pubMethod1()
{
DMockRepo::getInstance().getMock(this).pubMethod1();
}
//
Non-public methods are irrelevant - so do whatever you like...
And use DMockRepo to set expectation on your D objects:
TEST(Usage,Example)
{
DMock dMock;
DMockRepo::getInstance().addMockToUse(&dMock);
SUT sut; // you should know how many D objects SUT needs - I assume just one
EXPECT_CALL(dMock, pubMethod1());
sut.doSomethingThatCallsDpubMethod1();
}

Related

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

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);
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.
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);
}

Google Test Framework: is better to use shadowing or virtual methods?

In the example below, I want to unit test class A in order to verify that when A::request is called, B::response() is called as well:
class A
{
public:
void request()
{
m_b.response();
}
private:
B m_b;
};
class B
{
public:
void response();
};
In order to do that, class B has to be mocked:
class MockB : public B
{
public:
MOCK_METHOD0( response, void());
};
So that the test will contain:
class TestA : public A
{
...
};
...
EXPECT_CALL( m_b, response( ) ).Times( 1 );
request( );
...
The question is: how to "inject" MockB as a replacement of B m_b?
First tecnique:
Create a ShadowB class that redirects the method call to class MockB. This requires the original code to be in an external binary, but does not require any change in the actual code.
Second tecnique:
Making B::response virtual
Changing B m_b to a std::unique_ptr<B> m_b
Replace m_b value with an instance of class MockB during the test setup
Second approach means more code change and I'm not sure about its pro.
The correct way of solving your problem is the second technique. More generally, it is very hard to 'retro-fit' unit testing code onto components that were not designed with it in mind - you almost always need to significantly modify the code being tested.
Using virtual functions to substitute Mock callback objects in place of real ones, both inheriting from a common interface is a very common approach. Another alternative is to have your classes being tested be template classes, and replace their template parameters with Mock objects.

Allow a mock class to inherit from a final class

We may declare a final/sealed non-inheritable class using the new C++ keyword final.
class Generator final
{
};
This class may inherit from other, may or may not have virtual (inherited or not). But, how to make it final, yet allow one class to inherit from it?
We mostly need to derive a mock class from real class (with or without late-binding, hence virtual isn't important). How to make it work:
class MockGenerator : Generator{};
But disallow any other inheritance?
But, how to make it final, yet allow one class to inherit from it?
That's not possible.
We mostly need to derive a mock class from real class (with or without late-binding, hence virtual isn't important).
If the class is final, you do not need to derive from it. If you do need to derive from it, it is not final. Pick one.
Edit: You can add restrictions to your class, but those come at their own cost to the interface:
class Generator // not final
{
Generator(); // the only accessible constructor is private
// whitelist who has access to this constructor
friend class MockGenerator;
public:
// no public constructors here except for copy & move
Generator(Generator&);
Generator(Generator&&);
...
// provide controlled access to the private constructor
static Generator make_generator() { return Generator(); }
// rest of API here
};
This is a class that allows it's factory and MockGenerator specializations to call it's constructor. This comes at the price of blocking trivial construction though.
Old code (no longer compilable):
Generator instance;
New code (enforced by the private constructor):
auto instance = Generator::make_generator();
One possibility: use a define for final and define it as empty when generating the test environment.
#ifdef MOCK
#define CLASS_FINAL
#else
#define CLASS_FINAL final
#endif
edit: I agree with the comment of utnapistim: this is not a recommendation, just a technical possibility (but at least better than #define final).
If you need to create mock class it for unit-testing, then you can try Typemock Isolator++. Because it easily handles with final classes. You don't even need to change something in you production code (like creation of separate mock class). I've created simple test to demonstrate it:
class Generator final
{
public:
int foo()
{
return 0;
}
};
TEST_METHOD(TestFinal)
{
Generator* generator = FAKE<Generator>();
WHEN_CALLED(generator->foo()).Return(1);
int result = generator->foo();
Assert::AreEqual(1, result);
}
Hope it can be useful for you.

How do I use GMock with dependency injection?

I have a class which carries a couple of dependencies which I'd like to mock using Google Mocks, in order to test the class with Google Test.
Simplified, I have the following1:
template<typename TDep>
class SUT {
private:
TDep dependency;
public:
explicit SUT(const TDep& dep) : dependency(dep) { }
SUT(const SUT& other) : dependency(dep.other) { }
// some methods that use the dependency
}
I also have an interface for the dependency,
class IDependency {
public:
virtual double calculateCoolStuff(double) const = 0;
virtual ~IDependency() { };
}
and a mock object
class MockDependency {
public:
MOCK_CONST_METHOD1(calculateCoolStuff, double(double));
};
However, when I try to compile something like
MockDependency mock;
SUT sut(mock);
I get errors stating error: use of deleted function MockDependency(const MockDependency&), i.e. there is no copy-constructor of the mocked object. I found this discussion on Google Groups which basically ends in making mock objects non-copyable, but allowing the user to add a copy constructor and define copy behavior manually. Very well:
class MockDependency {
public:
MockDependency(const MockDependency& other) { }
MOCK_CONST_METHOD1(calculateCoolStuff, double(double));
};
Now my code compiles, but if I run something like
MockDependency mock;
SUT sut(mock);
EXPECT_CALL(mock, calculateCoolStuff(2.0)).WillRepeatedly(Return(3.0));
sut.doStuff(); // Calls calculateCoolStuff
in a test, I get an error stating that the call was never set up. In other words, the instance mock which I can use to setup expectations, is no longer the same as the instance on SUT used for calculations. This makes testing with GMock and DI difficult, to say the least...
What is the best solution to this?
1) Yes, I'm using poor man's DI. Not the topic of this conversation...
You can use dependency injection with references by ensuring that your class member is a reference:
template<typename TDep>
class SUT {
private:
TDep& dependency; // Reference
// etc.
}
Note that you no longer need a copy constructor on MockDependency. As a rule, you need access to all instances of mock objects being used by your SUT to set up expectations on them.

How do you design a C++ application so that Mock Objects are easiest to use?

I've never developed using Test Driven Development, and I've never used Mock Objects for unit testing. I've always unit tested simple objects that don't incorporate other aspects of the application, and then moved on to less simple objects that only reference objects that have already been unit tested. This tends to progress until the final "unit" test is a component test.
What design techniques are used to make the replacing of internal classes with Mock Objects as easy as possible?
For example, in my code, I would include the header file for myDataClass within myWorkerClass. myDataClass is constructed by myWorkerClass, and its lifetime is tied to myWorkerClass. How can you set it up so that it would include a mock myDataClass when the include is hard-wired?
A beginners answer would be:
in tested class don't use the actual
type of mocked one, use its
interface
while testing provide
another realization of mocked object
interface
//Common header
class ObjectInterface {
public:
virtual void doThings()=0;
};
//Release
class RealObject: public ObjectInterface {
public:
virtual void doThings(){
//Complicated work here
}
};
//Testing
class MockedObject: public ObjectInterface {
public:
virtual void doThings(){
//Not so complicated work here
}
};
//Common header
class TestedClass {
public:
void useObject(ObjectInterface & object) {
object->doThings();
}
};
//Unit test
TestedClass toTest;
MockedObject mockedObject;
toTest.useObject(mockedObject);
You could look to adapt your code to follow an (Abstract) Factory Design pattern, whereby a different factory could be used in a unit test environment that would create your mock objects.
One way would be to not hard-wire your classes like that.
Using your example:
myDataClass would be a pure virtual class. This would have at least 2 implementations, the 'real' one and the mock.
Your test code could inject a mock instance by having 2 constructors, one that takes a 'myDataClass' and one that doesn't. See the code below for an example.
class myWorkerClass {
public:
myWorkerClass(myDataClass * dc) : m_dc(dc) {}
myWorkerClass() : m_dc(new MyRealDataClass()) { }
~myWorkerClass { delete m_dc; }
private:
myDataClass *m_dc;
}
Now, you can provide any implementation of the myDataClass to the myWorkerClass you want. If you don't provide an implementation, then your code falls back on the 'real' implementation.
Another technique would be to use the Factory pattern to instantiate your objects. Your test code could set some flag on the factory that creates instances of myDataClass and have it produce a mock object instead of the real one. I prefer the first technique as to me it's a little easier to use (plus I don't have to maintain a factory class for everything I want to test)