Reputation: 947
I just started working on unit testing (using BOOST framework for testing, but for mocks I have to use Google Mock) and I have this situation :
class A
{
static int Method1(int a, int b){return a+b;}
};
class B
{
static int Method2(int a, int b){ return A::Method1(a,b);}
};
So, I need to create mock class A, and to make my class B not to use real Method1 from A class, but to use mock.
I'm not sure how to do this, and I could not find some similar example.
Upvotes: 26
Views: 52213
Reputation: 64223
You could change class B into a template :
template< typename T >
class B
{
public:
static int Method2(int a, int b){ return T::Method1(a,b);}
};
and then create a mock :
struct MockA
{
static MockCalc *mock;
//This class is passed as template type during class B object creation in unit test environment
static int Method1(int a, int b){ return mock->Method1(a,b);}
};
class MockCalc {
public:
MOCK_METHOD2(Method1, int(int,int));
};
Before every test, initialize the static mock object MockA::mock
.
Another option is to instead call directly A::Method1
, create a functor object (maybe std::function type) in class B, and call that in the Method2. Then, it is simpler, because you would not need MockA, because you would create a callback to MockCalc::Method1 to this object. Something like this :
class B
{
public:
static std::function< int(int,int) > f;
static int Method2(int a, int b){ return f(a,b);}
};
class MockCalc {
public:
MOCK_METHOD2(Method1, int(int,int));
};
and to initialize it :
MockCalc mock;
B::f = [&mock](int a,int b){return mock.Method1(a,b);};
Upvotes: 37
Reputation: 11
A variant version based on BЈовић's answer that allows not to use template (and error-prone explicit template specialization if your implementation is not in the header files). However, this will need to make the class A not static anymore.
First, create an interface class
class AIf
{
int Method1(int a, int b) = 0;
};
Let your class A implements AIf
class A : AIf
{
int Method1(int a, int b){return a+b;}
};
Then in your class B, add a static pointer to the AIf
class B
{
static AIf* impl = nullptr;
static int Method2(int a, int b) {return impl->Method1(a, b)}
};
When GMock, just do
class MockA : AIf {
MOCK_METHOD2(Method1, int(int a, int b));
};
Then in your tests, set the impl before calling any functions
MockA mockA;
EXPECT_CALL(...);
B::impl = &mockA;
B::Method2(a, b);
Upvotes: 1
Reputation: 21
jomock is one of the feasible solutions for Windows application case
class A
{
public:
static int Method1(int a, int b) { return a + b; }
};
class B : public A
{
public:
static int Method2(int a, int b){
return A::Method1(a, b);
}
};
TEST(JoMock, Method1Test)
{
EXPECT_CALL(JOMOCK(A::Method1), JOMOCK_FUNC(_, _))
.WillRepeatedly(Return(3));
EXPECT_EQ(B::Method2(1, 3), 3);
}
B::Method2(1, 3) returns 3 in this case.
Upvotes: 2