Reputation: 455
I am using google test for adding couple of unit tests in the program(C++). One of the class is using the member variable of the base template class.
For example:
template <typename foo>
class bar : public foo
{
// let's say foo has a member variable alpha
// using foo::alpha in bar
};
Now, for testing the bar class, I am mocking the foo class to be passed to bar. I mocked the functions of foo
fine, but not sure how to handle the variables used from the base class? Like here I'm using the alpha
variable.
For example:
struct Mockfoo
{
// Mock Methods here
// Not sure about variables??
};
bar<Mockfoo> b;
I am new to gtest/gmock. Have you encountered such cases and how to handle it? I am only interested in checking the behaviour of the function calls, so just wanted to somehow bypass the variable dependency.
Note: The variables are kind of complex, they need a couple of objects to initialize it, that means I need to mock them too. So, I am more biased towards some way of bypassing it.
Upvotes: 1
Views: 514
Reputation: 7556
It's a bit odd (but doable) that you are testing a class bar
and you want to mock its parent class foo
. Ideally you want to keep your class-under-test and mocked collaborator classes separate.
If you want to do this, when you mock foo
, you can mock alpha
without the need for other objects. Say foo
is originally defined as:
// Real foo used in production
struct foo {
// Initializing alpha using other objects
foo(OtherClass1 o1, OtherClass2 o2) : alpha(o1, o2) {}
int SomeFunction() { return 0; }
ComplexVariable alpha;
};
Then your mocked foo
can be:
// Mocked complex variable
struct MockedComplexVariable {
public:
MOCK_METHOD(int, get, (), ());
};
struct Mockfoo {
// Mock Methods here
// Not sure about variables??
public:
MOCK_METHOD(int, SomeFunction, (), ());
MockedComplexVariable alpha; // ---> Doesn't need other objects!
};
Here is the complete example:
using ::testing::Return;
//-----------------------------------------------------------------------------
// Real classes used in production
//-----------------------------------------------------------------------------
class OtherClass1 {
//...
};
class OtherClass2 {
//...
};
class ComplexVariable {
public:
ComplexVariable(OtherClass1 o1, OtherClass2 o2) {}
//...
};
// Real foo used in production
struct foo {
// Initializing alpha using other objects
foo(OtherClass1 o1, OtherClass2 o2) : alpha(o1, o2) {}
int SomeFunction() { return 0; }
ComplexVariable alpha;
};
//-----------------------------------------------------------------------------
// Mocked classes used in test
//-----------------------------------------------------------------------------
// Mocked complex variable
struct MockedComplexVariable {
public:
MOCK_METHOD(int, get, (), ());
};
struct Mockfoo {
// Mock Methods here
// Not sure about variables??
public:
MOCK_METHOD(int, SomeFunction, (), ());
MockedComplexVariable alpha; // ----> Doesn't need other objects!
};
template <typename foo>
class bar : public foo {
public:
// let's say foo has a member variable alpha
// using foo::alpha in bar
int UsingAlpha() { return foo::alpha.get() + foo::SomeFunction(); }
};
TEST(TestFoo, UsingAlpha) {
bar<Mockfoo> b;
EXPECT_CALL(b, SomeFunction()).WillOnce(Return(1)).WillOnce(Return(2));
EXPECT_CALL(b.alpha, get()).WillOnce(Return(10)).WillOnce(Return(20));
EXPECT_EQ(b.UsingAlpha(), 11);
EXPECT_EQ(b.UsingAlpha(), 22);
}
Live example: https://godbolt.org/z/bs8PEWxxb
Upvotes: 0