I am unit testing a derived class and want to EXPECT_CALL that a certain method belonging to its base class is called.
For example:
class Base {
public:
void move(int x, int y);
};
class Derived: public Base{
public:
RESULT update();
private:
int age;
};
HRESULT Derived::update(void) {
int param1 = 5, param2 = 10;
move(param1, param2);
age++;
return SUCCESS;
}
I can't just create a mock for Derived and expect move since there is no dependency and the actual move() will be called.
How can I be able to mock move()? My end goal is that I need to expect move() to be called with CORRECT parameter values (param1 and param2 in this case).
Of course this isn't the actual code but just a representation
I know this is not good design as far as UT is concerned, but this is to test some legacy code I am not allowed to reformat (but need to make UT). So being able to mock and test move() is the best option I have really.
Help will be appreciated. Thanks!
I don't think there is any way without using some preprocessing tricks. And of those tricks making method virtual when testing should be least painfull.
It is enough to do something like:
#if UNDER_TEST
#define TEST_VIRTUAL virtual
#else
#define TEST_VIRTUAL
#endif
class Base {
public:
TEST_VIRTUAL void move(int x, int y);
};
Then you can mock it like this:
class TestObject : public Derived {
public:
MOCK_METHOD2(move, void(int x, int y));
};
TEST(Test, Testing)
{
TestObject obj;
EXPECT_CALL(obj, move(5, 10));
obj.update();
}
In this code there is noting to mock. You do not have here any external dependency.
Test for this code can look like this:
TEST(DerivedTest, WhenUpdateIsCalledPossitionIsChangedAndItGetsOlder)
{
Derived foo;
foo.age = 1;
foo.update();
EXPECT_EQ(10, foo.x);
EXPECT_EQ(12, foo.y);
EXPECT_EQ(2, foo.age);
}
Show me the reason there is sense to mock here anything?
Related
#include "gtest/gtest.h"
#include "gmock/gmock.h"
class Turtle{
public:
int foo();
};
int func(){
Turtle local_tutrtle;
auto x = local_tutle.foo();
......
return x;
}
TEST(mock, foo) {
class MockTurtle : public Turtle {
public:
MOCK_METHOD0(foo, int());
};
ASSERT_EQ(10, func());
}
How can I mock the local_turtle in func()? I want to change the return value of local_tutle.foo() without modifying func();
Thanks.
You can't.
You have to supplement mocked object (in your example turtle) from the outside, by passing (mocked or nomral) turtle object as an argument.
This design pattern is called dependency injection, and you should get familiar with it as soon as possible, because it's very important in designing easily testable applications and frequently used.
Let's say that I have this class in C++:
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
}
How can I unit test exampleMethod()? I would like to do something like this:
void testExampleMethod(){
ExampleClass obj;
int before_call_value = obj.example_var;
obj.exampleMethod();
int after_call_value = obj.example_var;
ASSERT_NOT_EQUALS(before_call_value, after_call_value);
}
But example_var is private.
So, what is the right way to do this unit test? How can I test if a private example_var has changed?
Short answer: Dont do it.
Your test should test against the public interface only. Let me try to explain with some code:
class Adder {
int a,b;
public:
Adder() : a(0),b(0) {}
void set(int x,int y) { a=x;b=y; }
int get() { return a+b; }
};
and a test (assume for a moment we had access to a and b):
void testAdder(){
Adder add;
int a = 1;
int b = 2;
add.set(a,b);
ASSERT_EQUALS(add.a,a);
ASSERT_EQUALS(add.b,b);
ASSERT_EQUALS(add.get(),a+b);
}
Suppose you already distributed the code and someone is using it. He would like to continue using it but complains about too much memory consumption. It is straightforward to fix this issue while keeping the same public interface:
class Adder {
int c;
public:
Adder() : c(0) {}
void set(int x,int y) { c = x+y; }
int get() { return c; }
};
That was easy, but the test will fail :(
Conclusion: Testing private implementation details defeats the purpose of testing, because each time you modify the code it is likely that you also have to "fix" the test.
It is bad approach to test private variable/methods. But if you need there are a lot of options:
You can make Your test class as friend of ExampleClass
You can grab information using moc object
If you want to access example_val, there are one of two things you can do. The first is by making testExampleMethod() a friend method, as follows:
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
friend void testExampleMethod(); //Now you can use the function as is.
}
On the other hand, you could just add a getter to your ExampleClass to access the variable, such as the following:
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
inline void getExampleVar() const { return example_var; }
}
And then change testExampleMethod() to:
void testExampleMethod(){
ExampleClass obj;
int before_call_value = obj.getExampleVar();
obj.exampleMethod();
int after_call_value = obj.getExampleVar();
ASSERT_NOT_EQUALS(before_call_value, after_call_value);
}
I would honestly use the second method, since accessing a class's private variables is generally not recommended.
You just simply implement get function for that private variable you want to get.
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
int GetExampleVar(){
return example_var;
}
}
And call it like
void testExampleMethod(){
ExampleClass obj;
int before_call_value = obj.GetExampleVar();
obj.exampleMethod();
int after_call_value = obj.GetExampleVar();
ASSERT_NOT_EQUALS(before_call_value, after_call_value);
}
Or make testExampleMethod friend function (friend function can access private variables of friend class even if its not its method).
class ExampleClass{
private:
int example_var;
public:
void exampleMethod(){
example_var = other_value; // other value will be always different
}
friend void testExampleMethod();
}
In my opinion first example would be more suitable, but if you cannot modify ExampleClass, you can turn off access control for gcc -- -fno-access-control.
A few options I can think of:
1) Make the test code a friend of the class. That way it can access the private members.
2) Add a getter to the class that's under a #ifdef Testing directive that only gets defined when building the test version (or put public: under that macro and a private: in the #else branch).
3) #define private public when building the test (no, not really).
4) Use gcc's -fno-access-control flag when building the version to test, so that everything is public (if you are using gcc that is).
5) Just give up testing externally from the class and instead add relevant static_asserts/asserts to the class itself to test invariants.
6) Don't. Just stick to testing the public interface.
Hope that helps :-)
This is very closely related to How to use gmock to test that a class calls it's base class' methods but I'm struggling to get this working with my example.
I'm using GTest and GMock to test drive a new feature so I have a base class...
class SimpleObject
{
public:
explicit SimpleObject() {}
virtual void moveX(int dX)
{
// Do important stuff like updating position, bounding box etc.
}
// ...
};
Based on other TDD I have a derived class and the new feature is such that when I call moveX on the derived object it will do something specific, however it also needs to do the important stuff in SimpleObject::moveX.
I already have test driven unit tests related to the SimpleObject::moveX function so I don't want to repeat them for the derived class. As long as I know SimpleObject::moveX is called then everything's hunky dory.
Anyway, based on the above link and following TDD I've ended up with the following.
The derived class:
class ComplexObject : public SimpleObject
{
public:
virtual void moveX(int dX)
{
// Do something specific
}
};
The 'testable' class:
class TestableComplexObject : public ComplexObject
{
public:
MOCK_METHOD1(moveX, void(int dX));
void doMoveX(int dX)
{
SimpleObject::moveX(dX);
}
};
The test:
TEST_F(ATestableComplexObject, CallsBaseClassMoveXWhenMoveXIsCalled)
{
int dX(8);
TestableComplexObject obj;
EXPECT_CALL(obj, moveX(dX))
.Times(1)
.WillRepeatedly(testing::Invoke(&obj, &TestableComplexObject::doMoveX));
obj.moveX(dX);
}
If I run my tests then everything passes. This isn't correct because as you can see ComplexObject::moveX doesn't do anything.
Also, regardless of what I put in doMoveX (which I thought was meant to set up my expectations) the tests will still pass.
I'm obviously missing something simple here, so any ideas?
Thanks for the comments, with a tweak to the design I am able to test what I want.
Firstly, create an interface for SimpleObject:
class ISimpleObject
{
public:
virtual void moveX(int dX) = 0;
};
My SimpleObject class then implements this:
class SimpleObject : public ISimpleObject
{
public:
explicit SimpleObject() {}
virtual void moveX(int dX)
{
(void) dX;
// Do important stuff like updating position, bounding box etc.
}
};
Instead of ComplexObject inheriting from SimpleObject, it inherits from the interface and owns a SimpleObject (i.e. it 'has a' rather than 'is a'). The constructor ensures we pass in a SimpleObject and it's this injection that makes mocking easier.
class ComplexObject : public ISimpleObject
{
public:
ComplexObject(SimpleObject *obj)
{
_obj = obj;
}
virtual void moveX(int dX)
{
_obj->moveX(dX);
}
private:
SimpleObject *_obj;
};
Now I simply mock the calls I'm interested in from SimpleObject
class SimpleObjectMock : public SimpleObject
{
public:
MOCK_METHOD1(moveX, void(int dX));
// Do important stuff like updating position, bounding box etc.
};
The test is simplified too
TEST_F(AComplexObject, CallsBaseClassMoveXWhenMoveX)
{
int dX(8);
SimpleObjectMock mock;
ComplexObject obj(&mock);
EXPECT_CALL(mock, moveX(dX)).Times(1);
obj.moveX(dX);
}
The behaviour is as expected. If the ComplexObject::moveX function is empty (as it will be at the start) then the test fails. It will only pass when you call SimpleObject::moveX.
You need to design your ComplexObject in a way that checking if SimpleObject::moveX was called is possible. One way to do it: encapsulate this base call with some other function that can be mocked:
class ComplexObject : public SimpleObject
{
public:
virtual void moveX(int dX)
{
// Call base function
baseMoveX(dx);
// Do something specific
}
protected:
virtual void baseMoveX(int dX)
{
SimpleObject::moveX(dx);
}
};
Then in your Testable class just mock this base function:
class TestableComplexObject : public ComplexObject
{
public:
MOCK_METHOD1(baseMoveX, void(int dX));
};
You cannot mock just moveX because - there is no way to distinguish between base and derived in such context.
So - your test can look like this:
TEST_F(ATestableComplexObject, CallsBaseClassMoveXWhenMoveXIsCalled)
{
int dX(8);
TestableComplexObject obj;
EXPECT_CALL(obj, baseMoveX(dX))
.WillOnce(testing::Invoke([&obj] (auto dx) {obj.SimpleObject::moveX(dx); }));
obj.moveX();
}
[UPDATE]
As it is discovered in comments - there is still a problem how to ensure ComplexObject::baseMoveX() calls SimpleObject::moveX.
The possible solution is to put one more class in between ComplexObject and SimpleObject.
template <typename BaseObject>
class IntermediateObject : public BaseObject
{
public:
virtual void baseMoveX(int dX)
{
BaseObject::moveX(dx);
}
};
With test ensuring this really happens:
class TestableBaseMock
{
public:
MOCK_METHOD1(moveX, void(int dX));
};
TEST(IntermediateObject Test, shallCallBaseMoveX)
{
const int dX = 8;
IntermediateObject<TestableBaseMock> objectUnderTest;
TestableBaseMock& baseMock = objectUnderTest;
EXPECT_CALL(baseMock, moveX(dX));
objectUnderTest.baseMoveX(dx);
}
Then - put it between Simple and Complex classes:
class ComplexObject : public IntermediateObject<SimpleObject>
{
public:
virtual void moveX(int dX)
{
// Call base function
baseMoveX(dx);
// Do something specific
}
};
At the end - I just want to emphasize that changing your original design - to use aggregation instead of inheritance (aka decorator design pattern) is the best way. First - as you can see in my answer - trying to stay with inheritance make the design worse if we want to test it. Second - tests for decorator kind of design are much simpler as it showed in one of the answers...
The main issue here is that, in method TestableComplexObject::doMoveX, you are calling method SimpleObject::moveX. This is why everything passes. You are supposed to call the method moveX that belongs to class ComplexObject. Therefore, changing method doMoveX to:
void doMoveX(int dX)
{
ComplexObject::moveX(dX);
}
will solve your problem.
There is one more issue with the code you've posted. The last statement in the test body should be:
obj.moveX(dX);
but I guess this is just an error made while writing the question?
Hope this helps!
I have a class that is subclass of an external class over which I don't have any control. The external class depend on system resources. For example
class MyClass : public ExternalBase // This class is from external framework and framework requires it to derive from this class.
{
int doSomePrivateThing(int );
public:
virtual int DoSomething(int );
virtual ~MyClass();
}
int MyClass::doSomePrivateThing(int )
{
// do some private task
}
int MyClass::DoSomething(int n)
{
// Do MyClass Specific task
int k = doSomePrivateThing(n);
return ExternalBase::DoSomething(k); // This function depends on external system resources.
// Probably try to communicate with remote server
// or attempt access Storage or Display device etc.
}
MyClass::~MyClass()
{}
How can I break the dependency of MyClass and write unit test for MyClass::DoSomething(). Using composition in place of inheritance is not a choice as framework requires classes to be derived from this base class.
I am using C++ and GoogleTest/Mock. But any generalized solution is appreciated.
Thanks in advance.
There are two ways. I call them "a little more correct" way and "very ugly" way.
The "more correct" way:
Enclose external class functions with some additional layer than can be partial mocked.
class MyClass : public ExternalBase // This class is from external framework and framework requires it to derive from this class.
{
int doSomePrivateThing(int );
public:
virtual void BaseDoSomething(int) { return ExternalBase::DoSomething(v); }
virtual int DoSomething(int v);
virtual ~MyClass();
};
int MyClass::DoSomething(int n)
{
// Do MyClass Specific task
int k = doSomePrivateThing(n);
return BaseDoSomething(k);
}
And partial mock in UT in this way:
class TestableMyClass : public MyClass
{
public:
using MyClass::MyClass;
MOCK_METHOD1(BaseDoSomething, int(int));
};
TEST(A,A)
{
TestableMyClass objectUnderTest;
EXPECT_CALL(objectUnderTest, BaseDoSomething(112));
objectUnderTest.DoSomething(112);
}
When you need to call also the true base class method in your test - use WillOnce(Invoke...) with EXPECT_CALL.
The "very ugly" way:
Provide your own UnitTest implementation of ExternalBase and link it to your test. This "UnitTest" impolementation of ExternalBase should be based on some global Mocks objects.
ExternalBaseMock.hpp:
class ExternalBaseMock
{
public:
MOCK_METHOD1(DoSomething, int(int));
};
extern ExternalBaseMock externalBaseMock;
ExternalBaseMock.cpp:
ExternalBaseMock externalBaseMock;
int ExternalBase::DoSomething(int n)
{
return externalBaseMock.DoSomething(n);
}
Then your tests:
#include "ExternalBaseMock.hpp"
TEST(A,A)
{
MyClass objectUnderTest;
EXPECT_CALL(externalBaseMock, DoSomething(112));
objectUnderTest.DoSomething(112);
}
I have see some sample code about gmock,
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <stdio.h>
#include <string>
class MockFoo {
public:
MockFoo() {}
MOCK_METHOD3(Bar, char(const std::string& s, int i, double x));
MOCK_METHOD2(Bar2, bool(int x, int y));
MOCK_METHOD2(Bar3, void(int x, int y));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
};
class GMockOutputTest : public testing::Test {
protected:
MockFoo foo_;
};
TEST_F(GMockOutputTest, ExpectedCall) {
testing::GMOCK_FLAG(verbose) = "info";
EXPECT_CALL(foo_, Bar2(0, _));
foo_.Bar2(0, 0); // Expected call
testing::GMOCK_FLAG(verbose) = "warning";
}
The mock class MockFoo is mocking three functions as is in the class body, but the class MockFoo does not inherit any class.
If I understand it correctly, the mock class can mock virtual and non-virtual functions.
1) Mocking virtual functions: mock class should inherit a base class being mocked, and all the functions in that class should be virtual, but in this example, there is no base class.
2) Mocking non-virtual functions: mock class does not need inherit any class, but it needs to add tamplate to the code in order to use hi-perf dependency injection.
Does the code above belong to any of the case? And what is it trying to mock? And how to understand it?
The key thing to remember here is that a mock class can override either virtual or non-virtual methods in a superclass, but it doesn't have to. Sometimes it's useful to define a totally standalone mock which doesn't conform to any particular interface or override any other functionality. Consider the case where you are testing a templatized class:
template <typename T>
class Foo {
public:
Foo(T* member) : _member(member) {}
void f() { _member->bar(); }
private:
T* _member;
};
You want to verify that class Foo invokes bar() on the template parameter class, but the template class doesn't need to conform to any formal interface; it just needs to expose a bar() method. In this case you might use a standalone mock:
class MockSomething {
public:
MOCK_METHOD0(bar, void());
};
Just like your example, this mock class has no relationship to another class or interface. It's a standalone mock, and it can be used just as you would any other:
TEST(StackOverflow, StandaloneMock) {
MockSomething mock;
EXPECT_CALL(mock, bar());
Foo<MockSomething> foo(&mock);
foo.f();
}
That code is to test the method Bar2() of template class NaggyMock. To be more precise, it is testing that when you call method Bar2() with parameters 0 and 0, that Bar2() method from the mock is going to be called.
You can look at that as a static dependency injection, since you inject dependency through a template parameter. I would say it is the case 2.
Assuming your template class NaggyMock looks like this :
template< typename Foo >
class NaggyMock
{
public:
bool Bar2(int x, int y)
{
if ( ( 0 == x ) && ( 0 == y ) )
{
return foo.Bar2( 0, 11 );
}
return false;
}
private:
Foo foo;
};
then in the unit test you are testing the case when both parameters are 0. If your real class is using some resource (reading from a network, or from a database, or a file, ...), then to avoid it, and make your unit test very fast, you are going to mock that object. And that is what you are doing. Instead of the class handing the real resource, you are injecting a mock object.
For more information, read :
What is Mocking?
Why prefer template method over dependency injection?