I am using VS2005 and gmock ver. 1.6 for unit testing.
I have the following code which I want to mock, but I cannot find a way to do so.
class A
{
virtual bool foo1() = 0;
virtual bool foo2() = 0;
};
class B : public A
{
virutal bool foo1();
virtual bool foo2();
static B* getInstance(int x);
static B* getInstance();
}
Where getInstance(int x) is just creating an instance of B and returns it. Whereas getInstance() just returns the already created instance by getInstance(int x);
I have the mock class,
class MockA : public A
{
MOCK_METHOD0(foo1, bool());
MOCK_METHOD0(foo2, bool());
}
In the sources, I am using
bool retVal = B::getInstance()->foo2()
How can I mock this behavior B::getInstance()?
I think that you have to use linker seam to do what you want.
Let's say that we have libraryToBeMocked with the interface placed in libraryToBeMocked.hpp:
#pragma once
class Base
{
public:
virtual bool evenCheck() = 0;
virtual bool oddCheck() = 0;
};
class Derived : public Base
{
public:
virtual bool evenCheck();
virtual bool oddCheck();
static Base* getInstance(int x);
static Base* getInstance();
private:
Derived(int x);
int x;
};
You should have noticed that I have altered your design. Both getInstance method returns pointer to Base not Derived. If you want to mock the logic clearly you should mock the pure interface Derived already has some logic in it. IMHO both getInstance methods should be moved to other class anyways.
The implementation of the library is in libraryToBeMockedImpl.cpp
#include "libraryToBeMocked.hpp"
#include <memory>
#include <cstdlib>
bool Derived::evenCheck() { return x % 2 == 0; }
bool Derived::oddCheck() { return x % 2 != 0; }
namespace
{
std::auto_ptr<Derived> current(NULL);
}
Base* Derived::getInstance(int x)
{
current.reset(new Derived(x));
return current.get();
}
Base* Derived::getInstance()
{
return current.get();
}
Derived::Derived(int x) : x(x) {}
There is also the logic which you want to test. testedLibrary.hpp:
#pragma once
bool isOdd(int x);
bool isEven(int x);
implementation testedLibraryImpl.cpp:
#include "testedLibrary.hpp"
#include "libraryToBeMocked.hpp"
bool isOdd(int x)
{
return Derived::getInstance(x)->oddCheck();
}
bool isEven(int x)
{
return Derived::getInstance(x)->evenCheck();
}
Dummy main in main.cpp:
#include <iostream>
#include "testedLibrary.hpp"
using namespace std;
int main()
{
int x;
cin >> x;
cout << x << " is odd:" << boolalpha << isOdd(x) << endl;
cout << x << " is even:" << boolalpha << isEven(x) << endl;
return 0;
}
I don't use VS, but I think all it takes is to add main.cpp testedLibraryImpl.cpp and libraryToBeMockedImpl.cpp to the project. I would rather use gcc:
g++ main.cpp libraryToBeMockedImpl.cpp testedLibraryImpl.cpp -o production
Well, let's start with my answer. I would create header file 'libraryMockSeam.hpp':
#pragma once
#include "libraryToBeMocked.hpp"
class Provider
{
public:
virtual Base* getInstance() = 0;
virtual Base* getInstance(int x) = 0;
};
Provider* registerNewMockProvider(Provider*);
and libraryMockSeam.cpp:
#include "libraryMockSeam.hpp"
namespace
{
Provider* currentProvider = 0;
}
Provider* registerNewMockProvider(Provider* newProvider)
{
Provider* t = currentProvider;
currentProvider = newProvider;
return t;
}
Base* Derived::getInstance()
{
return currentProvider->getInstance();
}
Base* Derived::getInstance(int x)
{
return currentProvider->getInstance(x);
}
As you can see this source file provides it's own implementation of getInstance methods. It delegates it to the registered Provider. The headers introduced the Provider interface and a function that allows to register your provider. That's it.
Let's look at the test:
#include "testedLibrary.hpp"
#include "libraryMockSeam.hpp"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using namespace ::testing;
class MockProvider : public Provider
{
public:
MOCK_METHOD1(getInstance, Base*(int x));
MOCK_METHOD0(getInstance, Base*());
};
class MyMock : public Base
{
public:
MOCK_METHOD0(evenCheck, bool());
MOCK_METHOD0(oddCheck, bool());
};
class MyTestSuite : public Test
{
public:
MyTestSuite()
{
registerNewMockProvider(&provider);
}
StrictMock<MyMock> mock;
StrictMock<MockProvider> provider;
};
TEST_F(MyTestSuite, checksForOddValue)
{
EXPECT_CALL(provider, getInstance(1)).Times(2).WillRepeatedly(Return(&mock));
EXPECT_CALL(mock, evenCheck()).WillOnce(Return(false));
EXPECT_CALL(mock, oddCheck()).WillOnce(Return(true));
EXPECT_TRUE(isOdd(1));
EXPECT_FALSE(isEven(1));
}
TEST_F(MyTestSuite, checksForEvenValue)
{
EXPECT_CALL(provider, getInstance(1)).Times(2).WillRepeatedly(Return(&mock));
EXPECT_CALL(mock, evenCheck()).WillOnce(Return(true));
EXPECT_CALL(mock, oddCheck()).WillOnce(Return(false));
EXPECT_TRUE(isEven(1));
EXPECT_FALSE(isOdd(1));
}
I would compile it like that:
g++ test.cpp testedLibraryImpl.cpp libraryMockSeam.cpp -lgmock -lgmock_main -lpthread -o test
You should notice that I did not provide libraryToBeMocked.cpp in this case, the implementation is already provided by libraryMockSeam.cpp. In case you would like to use whole libraries (that is *.lib files(or *.a)) You would be able to provide both mocked library and the seam but later one should be provided to the linker before the library.
Related
I have a function1 inside which function 2 is called. I have to mock only function2, whwenever i call function1 it should call real implementation of function1 and mock implementation of function2. Kindly help me on this
Display.cpp
#include "Display.h"
int DisIp::getip()
{
return 5;
}
int DisIp::display()
{
Addition obj;
int ip=obj.getip();
return ip;
}
Display.h
class DisIP
{
public:
int display();
int getip();
};
GMOCK file
#include <limits.h>
#include "gmock.h"
#include "gtest.h"
#include "Display.h"
#include <string>
using namespace std;
using ::testing::AtLeast;
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Gt;
using ::testing::Return;
using testing::ReturnPointee;
using ::testing::Invoke;
class MyInterface{
public:
virtual int display() = 0;
virtual int getip()=0;
};
class MockInter : public MyInterface
{
public:
MockInter()
{
ON_CALL(*this, getip()).WillByDefault(Invoke(&this, &MockInter::getip));
ON_CALL(*this, display()).WillByDefault(Invoke(&real, &Addition::display));
}
MOCK_METHOD0(display,int());
MOCK_METHOD0(getip,int());
DisIp real;
};
class DisplayTest : public ::testing::Test {
protected:
virtual void SetUp() {
}
virtual void TearDown() {
// Code here will be called immediately after each test
// (right before the destructor).
}
};
TEST_F(DisplayTest,ip){
MockInter mock;
//EXPECT_EQ(1,mock.display());
EXPECT_EQ(1,mock.getip());
}
Your design suffers from breaking Single Responsibility Principle.
Displaying and getting IP are two different responsibilities. It is even shown in your implementation of DisIp::display() - you get IP from so-called Addition obj. When you fix this design error - your unit tests becomes much easier and straightforward. But it is important to say that UT are only the symptom here, the bad design is a disease.
So how it could look like:
class IIpProvider
{
public:
virtual ~IIpProvider() = default;
virtual int getIp() = 0;
};
class DispIp
{
public:
DispIp(IIpProvider& ipProvider) : ipProvider(ipProvider) {}
int display()
{
int ip=ipProvider.getIp();
//...
return ip;
}
private:
IIpProvider& ipProvider;
};
then your Mock:
class IpProviderMock : public IIpProvider
{
public:
MOCK_METHOD0(getIp, int());
};
And your tests:
class DispIpTest : public ::testing::Test
{
protected:
IpProviderMock ipProviderMock;
DispIp objectUnderTest{ipProviderMock}; // object-under-test must be connected to object doubles (like mocks)
};
TEST_F(DispIpTest, shallUseProvidedIpToDisplay)
{
using namespace testing;
auto SOME_IP = 7;
EXPECT_CALL(ipProviderMock, getIp()).WillRepeatedly(Return(SOME_IP));
//...
ASSERT_EQ(SOME_IP, objectUnderTest.display());
}
In your original tests - main problem was also that your mock object was not connected in any way to your object under test.
If you do not like (cannot) to change your design (what I really advice) you have to use technique called partial mocking
In your case - it would something like this:
class DisIP
{
public:
int display();
virtual int getip(); // function for partial mocking must be virtual
};
class DisIPGetIpMock : public DisIP
{
public:
MOCK_METHOD0(getIp, int());
};
class DispIpTest : public ::testing::Test
{
protected:
DisIPGetIpMock objectUnderTest;
};
TEST_F(DispIpTest, shallUseProvidedIpToDisplay)
{
EXPECT_CALL(objectUnderTest, getIp()).WillRepeatedly(Return(SOME_IP));
...
ASSERT_EQ(SOME_IP, objectUnderTest.display());
}
You can use the Cutie library to mock C function GoogleMock style, if that will assist you.
There's a full sample in the repo, but just a taste:
INSTALL_MOCK(fclose);
CUTIE_EXPECT_CALL(fclose, _).WillOnce(Return(i));
In Objective C the language has built in support for delegation of classes to other classes. C++ does not have such feature (one class as a delegate of another class) as part of the language. A way to mimic that is to separate declaration and implementation this way:
In header file a.h:
class AImpl;
class A
{
public:
A();
void f1();
int f2(int a, int b);
// A's other methods...
private:
AImpl *mImpl;
};
In the .cpp (implementation file):
#include "a.h"
class AImpl
{
public:
AImpl();
// repeating the same method declarations from A
void f1();
int f2(int a, int b);
// AImpl's other methods
};
AImpl::AImpl()
{
}
void AImpl:f1()
{
// actual implemetation
}
int AImpl::f2(int a, int b)
{
// actual implmentation
}
// AImpl's other methods implementation
A::A()
{
mImpl = new AImpl();
}
// A's "forwarder"
void A::f1()
{
mImpl->f1();
}
int A::f2(int a, int b)
{
return mImpl->f2(a, b);
}
// etc.
This requires manually creating all "forwarder" functions in the class that would delegate to another class to do the actual work. Tedious, to say the least.
The question is: is there a better or more productive way to achieve this effect using templates or other C++ langage constructs?
Yes it's possible. One of possible examples is:
struct WidgetDelegate
{
virtual ~WidgetDelegate() {}
virtual void onNameChange(std::string newname, std::string oldname) {}
};
class Widget
{
public:
std::shared_ptr<WidgetDelegate> delegate;
explicit Widget(std::string name) : m_name(name){}
void setName(std::string name) {
if (delegate) delegate->onNameChange(name, m_name);
m_name = name;
}
private:
std::string m_name;
};
Usage:
class MyWidgetDelegate : public WidgetDelegate
{
public:
virtual void onNameChange(std::string newname, std::string oldname) {
std::cout << "Widget old name: " << oldname << " and new name: " << newname << std::endl;
}
};
int main()
{
Widget my_widget("Button");
my_widget.delegate = std::make_shared<MyWidgetDelegate>();
my_widget.setName("DoSomeThing");
return 0;
}
Required includes are:
#include <string>
#include <iostream>
#include <memory>
You can implement a virtual interface in the base class.
However, if you really want to delegate, then you can overload the operator-> to delegate all calls.
You won't need anymore the forwarding methods:
#include <iostream>
#include <string>
using namespace std;
class AImpl;
class A
{
public:
A();
//Overloading operator -> delegates the calls to AImpl class
AImpl* operator->() const { return mImpl; }
private:
AImpl *mImpl;
};
class AImpl
{
public:
void f1() { std::cout << "Called f1()\n"; }
void f2() { std::cout << "Called f2()\n"; }
};
A::A()
{
mImpl = new AImpl();
}
int main()
{
A a;
a->f1(); //use a as if its a pointer, and call functions of A
A* a1 = new A();
(*a1)->f2();
}
I need to write the gtest to test some existing code that has a non-virtual method, hence I am testing using the below source, but I am getting the compilation error
package/web/webscr/sample_template_class3.cpp: In function âint main()â:
package/web/webscr/sample_template_class3.cpp:64: error: âclass Templatemyclassâ has no member named âgmock_displayâ
sample_template_class3.cpp
#include <iostream>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using namespace std;
template < class myclass>
class Templatemyclass
{
private:
myclass T;
public :
void display()
{
T.display();
}
};
class Test
{
public:
void display()
{
cout<<"Inside the display Test:" <<endl;
}
};
class MockTest
{
public:
MOCK_METHOD0(display,void());
};
class FinalTest
{
public:
void show( Templatemyclass<Test> t)
{
t.display();
cout<<"Inside the display FinalTest:" <<endl;
}
};
int main()
{
FinalTest test1;
Templatemyclass<Test> obj1;
Templatemyclass<MockTest> obj2;
EXPECT_CALL(obj2,display()).Times(1);
test1.show(obj1);
return 1;
}
There are a couple of issues in your code. I have changed it below and commented the code by way of explanation. If this is not clear enough, add a comment and I'll try and explain further.
#include <iostream>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using namespace std;
template <class myclass>
class Templatemyclass {
private:
// Hold a non-const ref or pointer to 'myclass' so that the actual
// object passed in the c'tor is used in 'display()'. If a copy is
// used instead, the mock expectations will not be met.
myclass* T;
public :
// Pass 'myclass' in the c'tor by non-const ref or pointer.
explicit Templatemyclass(myclass* t) : T(t) {}
void display() { T->display(); }
};
class Test {
public:
void display() { cout << "Inside the display Test:" << endl; }
};
class MockTest {
public:
MOCK_METHOD0(display, void());
};
class FinalTest {
public:
// Templatise this function so we can pass either a Templatemyclass<Test>
// or a Templatemyclass<MockTest>. Pass using non-const ref or pointer
// again so that the actual instance with the mock expectations set on it
// will be used, and not a copy of that object.
template<class T>
void show(T& t) {
t.display();
cout<<"Inside the display FinalTest:" <<endl;
}
};
int main() {
Test test;
Templatemyclass<Test> obj1(&test);
MockTest mock_test;
Templatemyclass<MockTest> obj2(&mock_test);
EXPECT_CALL(mock_test,display()).Times(1);
FinalTest test1;
test1.show(obj1);
test1.show(obj2);
return 0;
}
The following could possibly simplify the case:
#include <iostream>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
template <class myclass>
class Templatemyclass {
public:
myclass T;
void show() const { T.display(); }
};
struct Test {
void display() const { std::cout << "Inside the display Test:\n"; }
};
struct MockTest {
MOCK_CONST_METHOD0(display, void());
};
int main() {
Templatemyclass<Test> obj1;
obj1.show();
Templatemyclass<MockTest> obj2;
EXPECT_CALL(obj2.T, display()).Times(1);
obj2.show();
return 0;
}
If you don't want to change your source code, you can leverage injector++.
Currently it only supports x86 Windows. But Linux and x64 Windows support will come soon. Below examples will give you a brief idea:
Mock non-virtual methods
Below example fakes BaseClassTest::getAnInteger() by using fakeFunc():
class FakeClassNonVirtualMethodTestFixture : public ::testing::Test
{
public:
int fakeFunc()
{
return 6;
}
};
TEST_F(FakeClassNonVirtualMethodTestFixture, FakeIntFunctionWhenCalled)
{
// Prepare
int expected = 6;
InjectorPP::Injector injector;
injector.whenCalled(INJECTORPP_MEMBER_FUNCTION(BaseClassTest::getAnInteger))
.willExecute(INJECTORPP_MEMBER_FUNCTION(FakeClassNonVirtualMethodTestFixture::fakeFunc));
BaseClassTest b = BaseClassTest();
// Act
// FakeFunc will be executed!
int actual = b.getAnInteger();
// Assert
EXPECT_EQ(expected, actual);
}
Mock virtual methods
Injector++ supports virtual method mocking (Amazing, huh?). Below is a simple example:
int FakeIntFuncForDerived()
{
return 2;
}
TEST_F(FakeClassVirtualMethodTestFixture, MockDerivedClassVirtualMemberFunctionWhenCalled)
{
// Prepare
int expected = 2;
BaseClassTest* derived = new SubClassTest();
InjectorPP::Injector injector;
injector.whenCalledVirtualMethod(derived, "getAnIntegerVirtual")
.willExecute(fakeIntFuncForDerived);
// Act
// FakeIntFuncForDerived() will be exectued!
int actual = derived->getAnIntegerVirtual();
// Assert
EXPECT_EQ(expected, actual);
delete derived;
derived = NULL;
}
Mock static methods
Injector++ supports static method mocking. Below is a simple example:
Address FakeGetAnAddress()
{
Address addr;
addr.setAddressLine("fakeAddressLine");
addr.setZipCode("fakeZipCode");
return addr;
}
TEST_F(FakeClassNonVirtualMethodTestFixture, FakeStaticFunctionReturnUserDefinedClassWhenCalled)
{
// Prepare
Address expected;
expected.setAddressLine("fakeAddressLine");
expected.setZipCode("fakeZipCode");
InjectorPP::Injector injector;
injector.whenCalled(INJECTORPP_STATIC_MEMBER_FUNCTION(BaseClassTest::getAnAddressStatic))
.willExecute(INJECTORPP_MEMBER_FUNCTION(FakeClassNonVirtualMethodTestFixture::fakeGetAnAddress));
// Act
// FakeGetAnAddress will be executed!
Address actual = BaseClassTest::getAnAddressStatic();
// Assert
EXPECT_EQ(expected, actual);
}
I have multiple classes that need to share a single instance of another class. Publicly it should be unknown that this class exists. Is it appropriate to do something like the following? (Was tested as written)
#include <iostream>
class hideme
{
private:
int a;
public:
void set(int b) { a = b; }
void add(int b) { a += b; }
int get() { return a; }
hideme() : a(0) { }
};
class HiddenWrapper
{
protected:
static hideme A;
};
hideme HiddenWrapper::A;
class addOne : public HiddenWrapper
{
public:
void add() { A.add(1); }
int get() { return A.get(); }
};
class addTwo : public HiddenWrapper
{
public:
void add() { A.add(2); }
int get() { return A.get(); }
};
int main()
{
addOne a;
addTwo b;
std::cout << "Initialized: " << a.get() << std::endl;
a.add();
std::cout << "Added one: " << a.get() << std::endl;
b.add();
std::cout << "Added two: " << b.get() << std::endl;
return 0;
}
For what it's worth, hideme is part of a library I'm attempting to design a facade around, and the other classes have members from the library that interact with the static hideme.
Additionally, if the header file written for HiddenWrapper has no corresponding source file, is that the best place to define its static member? With an include guard.
Is there any other method to solve this problem? As far as I could imagine (not terribly far) I could only solve it otherwise with friendship, which I am wary of.
You can prevent access to a class by not making it accessible outside the translation unit that uses it.
// public_header.h
class A {
void bar();
};
class B {
void foo();
}
// private_implementation.cpp
#include "public_header.h"
namespace {
class hidden { void baz() {} };
hidden h;
}
void A::bar() {
h.baz();
}
void B::foo() {
h.baz();
}
This class will be usable only by A::bar and B::foo. The type hidden and the variable h still technically have external linkage, but no other translation unit can say their names.
Sometimes it is a better idea to inject shared ressources (by reference or pointer) through the constructor (also known as composition instead of inheritance). This way gives you the ability to share or not (e.g. to have a thread-safe variant of your code which is not). See http://de.wikipedia.org/wiki/Inversion_of_Control principle for more info.
This implements a singleton around some other class and hides it from
users:
class hideme {};
// fwd declarations
class x;
// library internal
class S
{
S() = delete;
S(S const&) = delete;
void operator=(S const&) = delete;
private:
static hideme& getInstance()
{
static hideme instance;
return instance;
}
friend x;
};
// library classes
class x {
hideme& s;
public:
x() : s(S::getInstance()) {}
};
int main()
{
x x;
return 0;
}
This does not handle cases where you actually want the hideme
instance to be destroyed when no other object is using it anymore. For
that you need to get a little bit more inventive using reference
counting.
I also should say that I think this is a bad idea. Singletons almost
always are.
Generally, the best approach, if you have a variable in the main part, and want to share it with all classes.
For example, if class X makes a change on this var, the change happened to the var in the main as well: you can use EXTEND
************************ The main *********************
#include <iostream>
using namespace std;
#include "Game.hpp"
//0: not specified yet; 1:singlemode; 2:multiplayerMode
int playingMode = 0;
int main()
{
Game game;
game.Run();
std::cout<< playingMode << std::endl;
return 0;
}
*********************** Class X *****************
#include <iostream>
using namespace std;
extern int playingMode;
....
....
if(m_isSinglePressed)
{
playingMode = 1;
...
}
else if(m_isMultiPressed)
{
playingMode = 2;
...
}
I wrote the following piece of code to test Xyz::xyz_func by mocking Abc::abc_func using Google Mock.
#include <iostream>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using namespace std;
using ::testing::_;
using ::testing::Return;
class Abc
{
public:
virtual ~Abc() {}
virtual bool abc_func(int arg) = 0;
};
class MockAbc : public Abc
{
public:
virtual ~MockAbc() { }
MOCK_METHOD1(abc_func, bool(int arg));
};
class AbcImpl : public Abc
{
public:
virtual bool abc_func(int arg)
{
cout << arg << " :: " << __FILE__ << " :: " << __LINE__ << endl;
return true;
}
};
class Xyz : public AbcImpl
{
public:
virtual ~Xyz() {}
virtual bool xyz_func()
{
AbcImpl obj;
return obj.abc_func(1);
}
};
TEST(AbcTest, func_success)
{
MockAbc *mock = new MockAbc();
EXPECT_CALL(*mock, abc_func(_)).WillOnce(Return(true));
Xyz test;
EXPECT_TRUE(test.xyz_func());
delete mock;
}
int main(int argc, char** argv)
{
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
But i get the below error. I want to know how we can tell Xyz class to call mock of abc_func instead of actual implementation. Could you please help me.
1 :: ./gmock_test.cpp :: 30
./gmock_test.cpp:50: Failure
Actual function call count doesn't match EXPECT_CALL(*mock, abc_func(_))...
Expected: to be called once
Actual: never called - unsatisfied and active
You are creating a mock object of type MockAbc but you never use it. From your code it appears that you're expecting the MockAbc instance you create to automagically replace the AbcImpl object that you explicitly create in Xyz::xyz_func.
What you need to be doing instead is using dependency inversion to allow the object used by xyz_func to be specified at runtime.
You don't need Xyz to inherit from AbcImpl or Abc.
Two potential solutions:
class Xyz {
public:
explicit Xyz(Abc& obj) :
obj(&) {
}
virtual bool xyz_func() {
return obj->abc_func(1);
}
private:
Abc* obj;
};
or
class Xyz {
public:
virtual bool xyz_func(Abc& obj) {
return obj->abc_func(1);
}
};