Here are the two classes you might be starting with:
Class you want to perform unit tests on:
class A {
public:
int do_a_work(B * bPtr) {
std::cout << "-- in a::do_a_work ---" << std::endl;
return 1 + bPtr->do_b_work();
}
};
Class you cannot modify:
// Class that we are *NOT* going to modify
class B {
public:
int do_b_work() {
std::cout << "-- in b::do_b_work ---" << std::endl;
return 2;
}
};
Your production (non-test) code.
A a;
B b;
a.do_a_work(&b); // b->do_b_work will be called ...
Update class A to use a template.
template <class B_class>
class A {
public:
int do_a_work(B_class * bPtr) {
std::cout << "-- in a::do_a_work ---" << std::endl;
return 1 + bPtr->do_b_work();
}
};
In production code, use the real B class.
A<B> aObj;
B bObj;
std::cout << aObj.do_a_work(&bObj) << std::endl;
In test code, use a mocked B class.
// Mock class.
// It doesn't inherit from B.
class B_Mock {
public:
MOCK_METHOD0(do_b_work, int());
};
Call the mock class in test code:
// Use the mocked class
B_Mock b;
A<B_Mock> a;
a.do_a_work(); // this will use the B_Mock->do_b_work MOCK_METHOD0.
Solution 2. Wrap the class you do not want to modify in a container.
Create a new class that contains an instance of the class that you do not want to modify.
// Add B Container class
class B_Container : public B{
private:
B my_b;
public:
B_Container() {}
// Make all public functions virtual (so that we can mock them out)
virtual int do_b_work() {
// Forward all work to B
return my_b.do_b_work();
}
// repeat for all other public functions ...
};
Then, modify class A to use B_container instead of B.
class A {
public:
int do_a_work(B_Container * bPtr) {
std::cout << "-- in a::do_a_work ---" << std::endl;
return 1 + bPtr->do_b_work();
}
};
In production, your code looks like this:
A a;
B_Container b; // This was just "B b;"
a.do_a_work(&b);
Now that the B_Container has a virtual function, you can mock out the calls like this:
class B_Mock : public B_Container{
public:
MOCK_METHOD0(do_b_work, int());
};
In test code, you can do this:
B_Mock b;
A a;
a.do_a_work(); // This will call B_Mock->do_b_work, which inherits from B_Container