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?
Related
the normal pattern of gmock testing is
class MyMockClass : public MyRealClass {
/// swap out behavior of an existng method
MOCK_method(some_method .....);
}
TEST() {
MyMockClass mock;
EXPECT_CALLED(mock.some_method);
/// ******* here I have to explicitly pass in the mock obj into the system
MyConsumerClass myconsumer(mock);
myconsumer.do_something_to_trigger_mock__some_method();
}
in the above "****" line I have to explicitly pass in a mock obj into the system, i.e. compose my consumer obj with a mock obj. But now I face an existing consumer class impl, its constructor does not allow passing in the dependency objects; in fact I can probably argue that it's impossible to list all the dependency objects in the ctor of a consumer class; more importantly, my real case is that the consumer class to be tested sits several levels above the mock obj:
class MyConsumerClass {
private:
MyHelperClass helper
public:
void trigger() {
helper.trigger_again();
}
}
class MyHelperClass {
BottomClass bottom;
public:
void trigger_again() {
bottom.do_something();
}
}
class BottomClass {
public :
void do_something();
}
in this case, in our unit test, we can only instantiate the top level MyConsumerClass, and I was hoping to verify that when I call myconsumer.trigger(), I could verify that the BottomClass.do_something() is called, possibly also verifying that it's called with a specific argument. But the above class hierarchy is written so that I can not pass in a mock BottomClass obj from the top level.
in jmock or jmockit, I remember it's possible to globally wipe out the behavior of BottomClass.do_something(), without referring to a specific mock obj, i.e. "static mocking", as they are called in jmockit. is it possible to do something like that in gmock (c++)? thanks
Converting the comment to an answer:
I can think of two things:
Why don't you test your classes separately? For example, write a separate test for MyHelperClass.
If dependency injection doesn't work for you, GMock allows you to do static mocking by templatizing your classes: Convert your classes to templates, then instantiate the template with real classes for production and with mock classes for testing. See here for an example.
In your case, your code could be rewritten to something like this:
//-----------------------------------------------------------------------------
// Real classes used in production
//-----------------------------------------------------------------------------
class BottomClass {
public:
void do_something();
};
//-----------------------------------------------------------------------------
// Templatized classes used in test or production
//-----------------------------------------------------------------------------
template <class BType>
class MyHelperClass {
public:
BType bottom;
public:
void trigger_again() { bottom.do_something(); }
};
template <class BType, template <typename> class HType>
class MyConsumerClass {
public:
HType<BType> helper;
public:
void trigger() { helper.trigger_again(); }
};
//-----------------------------------------------------------------------------
// Mocked classes used in test
//-----------------------------------------------------------------------------
class MockedBottomClass {
public:
MOCK_METHOD(void, do_something, (), ());
};
TEST(BottomClassTest, Test1) {
MyConsumerClass<MockedBottomClass, MyHelperClass> mock;
EXPECT_CALL(mock.helper.bottom, do_something());
mock.trigger();
}
I had to convert some of your private members to public members for the test to work.
Live example here: https://godbolt.org/z/qc3chdxKz
I have a test fixture in my tests so I don't have to instantiate objects of my class repeatedly, but I'm not sure how to use mocks with it. To put it simply, this is how the class is defined:
class Class1 {
public:
Class1(std::shared_ptr<Class2> class_two);
void doThisThing() { doThatThing(); }
}
class Class2 {
public:
Class2(Class3* class3_ptr);
int doThatThing();
}
(class 1 is constructed using a shared pointer to class 2. Class 2 is constructed with a pointer to class 3. Class 1 calls on a function "doThisThing" which calls Class 2's function doThatThing.)
I need to create a mock for doThatThing() (and the rest of Class2's functions), but can't figure out how to pass the mock object to Class 1. Here is what I have so far in my testing code:
class TestClass1 : public ::testing::Test {
TestClass1(){
//Construct instance of Class1 and store as member variable
std::shared_ptr<Class3> class_three = std::make_shared<Class3>();
std::shared_ptr<Class2> class_two = std::make_shared<Class2>((Class3*)class_three.get());
class_one = new Class1(class_two);
};
Class1* class_one;
}
MockClass2 : public Class2 {
MOCK_METHOD0(doThatThing, int());
}
TEST_F(TestClass1, doThatThingTest){
MockClass2 mockObj;
**THIS IS WHERE I'M STUCK. How do I get that mockObj into my TestClass1 Fixture? As of now, it is calling the actual function, not the mock***
class_one->doThatThing();
EXPECT_CALL(mockObj, doThatThing());
}
I had to abstract and simplify the actual code, so I hope the above makes sense.
Assuming that your MockClass2 works, you should try something like the following:
Here you should override the functions SetUp that is called right before every call of a test function to prepare your test data. And override TearDown that is called after every call of a test function to clean up test data.
struct TestClass1 : public ::testing::Test
{
void SetUp() override
{
class_two_mock = std::make_shared<MockClass2>();
class_one = std::make_unique<Class1>(class_two_mock);
}
void TearDown() override
{
class_one.reset();
class_two_mock.reset();
}
std::shared_ptr<MockClass2> class_two_mock
std::unique_ptr<Class1> class_one;
};
In the test function you must declare your expectations before something is executed.
TEST_F(TestClass1, doThatThingTest)
{
EXPECT_CALL(*class_two_mock, doThatThing());
class_one->doThatThing();
}
You may need an interface for Class2. The code here is not tested.
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?
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);
}
Google suggests delegating calls to a parent object when you need to invoke functionality of the real object, however this does not really create a partial (hybrid) mock. When invoking the real object, any method calls are those of the real object and not the mock object, on which you may have set up actions/expectations. How do I create a partial mock that delegates only specific methods to the real object, and all other method calls to the mock object?
Delegate to real object example
using ::testing::_;
using ::testing::AtLeast;
using ::testing::Invoke;
class MockFoo : public Foo {
public:
MockFoo() {
// By default, all calls are delegated to the real object.
ON_CALL(*this, DoThis())
.WillByDefault(Invoke(&real_, &Foo::DoThis));
ON_CALL(*this, DoThat(_))
.WillByDefault(Invoke(&real_, &Foo::DoThat));
...
}
MOCK_METHOD0(DoThis, ...);
MOCK_METHOD1(DoThat, ...);
...
private:
Foo real_;
};
...
MockFoo mock;
EXPECT_CALL(mock, DoThis())
.Times(3);
EXPECT_CALL(mock, DoThat("Hi"))
.Times(AtLeast(1));
... use mock in test ...
Instead of creating an instance of the real object as a member variable, the mock should simply extend the real object, then delegate all calls to the parent by default. You can now setup your mock like normal; setting a new ON_CALL will override the default call to the parent. We let polymorphism do the work for us -- all calls, even from the parent (real) object, invoke the mock object, then the ON_CALL statement was set to invoke either the parent object or the mock behavior. We have successfully mixed real object behavior with mock behavior. This is exactly the same as delegating calls to a parent class.
Delegate to parent class example
class Foo {
public:
virtual ~Foo();
virtual void Pure(int n) = 0;
virtual int Concrete(const char* str) { ... }
};
class MockFoo : public Foo {
public:
// Mocking a pure method.
MOCK_METHOD1(Pure, void(int n));
// Mocking a concrete method. Foo::Concrete() is shadowed.
MOCK_METHOD1(Concrete, int(const char* str));
// Use this to call Concrete() defined in Foo.
int FooConcrete(const char* str) { return Foo::Concrete(str); }
};
using ::testing::Invoke;
// Create mock instance foo.
...
// Delegate to parent.
ON_CALL(foo, Concrete(_))
.WillByDefault(Invoke(&foo, &MockFoo::FooConcrete));
The only downside to this technique is that it requires a lot of boilerplate code and is sensitive to code changes. I have extended googlemock to ease this process; the code is available here. It will generate partial mocks that call the parent (real) object by default for all methods, and generate matching constructors that pass arguments to the parent constructor.
The official Google Mock guideline and also the last proposal do work however introduce a lot of boilerplate code.
So here is my proposal:
Foo.h
class Foo {
public:
virtual ~Foo();
virtual void Pure(int n) = 0;
virtual int Concrete(const char* str) { ... }
};
MockFoo.h
class MockFoo: public Foo {
using Real = Foo;
public:
MockFoo();
virtual ~MockFoo();
MOCK_METHOD1(Pure, void(int n));
MOCK_METHOD1(Concrete, int(const char* str));
};
MockFoo.cpp
MockFoo::MockFoo() {
using ::testing::Invoke;
ON_CALL(*this, Pure()).WillByDefault(Invoke([this] {return Real::Pure();}));
ON_CALL(*this, Concrete()).WillByDefault(Invoke([this] {return Real::Concrete();}));
};
MockFoo::~MockFoo() = default;
It's worth noting that having an implementation file for the mock is a good practice with observable benefits for test compilation time. Nice and easy.