Google Mock: How to test this code? - c++

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);
}
};

Related

Trigger added methods of derived class by method in base class

I want to implement a simple test structure. Here is how I created base class and derived class.
testBase.h:
class TestBase {
public:
TestBase() {}
virtual void TestStart() = 0;
virtual void TestEnd() = 0;
void RunTest() {
// I need code here to trigger a chain of calls
}
};
classifierTest.h:
#include "testBase.h"
class ClassifierTest: public TestBase
{
public:
ClassifierTest() {
}
void TestStart();
void TestEnd();
void Test1();
void Test2();
void Test3();
};
classifierTest.cpp:
#include "classifierTest.h"
void ClassifierTest::TestStart() {
}
void ClassifierTest::TestEnd() {
}
void ClassifierTest::Test1(){
}
void ClassifierTest::Test2(){
}
void ClassifierTest::Test3(){
}
main function:
ClassifierTest *classifierTest = new ClassifierTest();
classifierTest->RunTest();
Suppose Test1(), Test2() and Test3() are my test methods, and I may add more tests here in future.
My goal is that when I call RunTest() in the main function, then these test methods are called one by one, after TestStart(), and before TestEnd().
so they would run like:
TestStart()
Test1()
TestEnd()
TestStart()
Test2()
TestEnd()
TestStart()
Test3()
TestEnd()
I don't want to specifically add test method in the base class. But the question is how to trigger these chain of calls from RunTest(). So the base trigger methods that it doesn't know about them.
I believe it should be sth like reflection in .net?
You are basically asking for reflection which isnt present in C++ (yet). Now the quesiton is what comprosmise you are willing to make.
If you are fine with writing some code to manually register the test functions, then they don't need to be members and a possible solution is this:
#include <functional>
#include <vector>
#include <iostream>
class TestBase {
public:
TestBase() {}
virtual void TestStart() = 0;
virtual void TestEnd() = 0;
void RunTest() {
for (const auto& test_fun : test_functions){
TestStart();
test_fun();
TestEnd();
}
}
using test_function = std::function<void()>;
void register_test(const test_function& fun){ test_functions.push_back(fun); }
private:
std::vector<test_function> test_functions;
};
class ClassifierTest: public TestBase
{
public:
ClassifierTest() {
register_test([](){ std::cout << "test 1\n";});
register_test([](){ std::cout << "test 2\n";});
}
void TestStart() { std::cout << "test start\n";}
void TestEnd() { std::cout << "test end\n";}
};
int main() {
ClassifierTest{}.RunTest();
}
Output:
test start
test 1
test end
test start
test 2
test end
Note that if you capture this the lambdas can use members, so there isnt much difference to your initial approach and the amount of code to write is also comparable:
class ClassifierTest2: public TestBase
{
public:
ClassifierTest2() {
register_test([this](){ std::cout << "test 1, x = " << x << "\n";});
register_test([this](){ std::cout << "test 2, x = " << x << "\n";});
}
void TestStart() { ++x;std::cout << "test start\n";}
void TestEnd() { std::cout << "test end\n";}
private:
int x = 0;
};
int main() {
ClassifierTest2{}.RunTest();
}
Output:
test start
test 1, x = 1
test end
test start
test 2, x = 2
test end
As mentioned already in a comment, if you manually register TestStart and TestEnd as well, then there is no need for the derived classes. It could be just a class Test with register_test_start(std::function<void()>) and register_test_end(std::function<void()>) or pass them as parameters to the constructor.

NVI doesn't prevent name hiding; why not use virtual final instead?

Consider the following:
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
class Foo {
public:
// NVI
bool method() {
cout << "Foo::method" << endl;
return method_impl();
}
// Why not do this instead?
//virtual bool method() final {
// cout << "Foo::method" << endl;
// return method_impl();
//}
private:
virtual bool method_impl() = 0;
};
class Bar : public Foo {
public:
// What stops someone from doing this hiding the Foo::method identifier?
// Uncomment the below and see how the console output is instead Bar::method and then method_impl
//bool method() {
// cout << "Bar::method" << endl;
// return method_impl();
//}
private:
virtual bool method_impl() override {
return true;
}
};
int _tmain(int argc, _TCHAR* argv[]) {
Bar bar = Bar();
cout << bar.method() << endl;
return 0;
}
As you can see above, the Foo class is trying to follow the NVI pattern with the Foo::method() member function.
What prevents a child class, in this case Bar, from hiding the Foo::method() with Bar::method()? I tried it and I guess nothing. If you uncomment Bar::method(), the console application does indeed go down the Bar implementation of method() which makes total sense.
Which begs the question, why not use virtual final to disallow name hiding of that method in a child class? Example provided in the Foo class.
Thanks

Alternative to virtual variables

I have two classes, Base and Derived. Derived inherits from Base and additionally includes several functions and variables -- therefore the need to have two separate classes. However, they do share one function, run.
In the example below I have to pass an argument to run in order to execute read - this argument depends on which class the object refers to. Is it possible to write a generic version of read such that the program automatically uses vars_Base or vars_Derived depending on which object calls run?
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
class Base
{
protected:
void read(std::vector<std::string>);
public:
void run(std::vector<std::string> vars) { read(vars); }
std::vector<std::string> vars_Base;
};
void Base::read(std::vector<std::string> int_vars)
{
for (auto int_vars_it : int_vars)
{
std::cout << int_vars_it << "\n";
}
}
class Derived : public Base
{
protected:
public:
std::vector<std::string> vars_Derived;
///Here are other functions only known to Derived, not Base
};
int main()
{
Base b;
b.vars_Base.push_back("aB");
b.vars_Base.push_back("bB");
b.vars_Base.push_back("cB");
b.run(b.vars_Base);
Derived d;
d.vars_Derived.push_back("aD");
d.vars_Derived.push_back("bD");
d.vars_Derived.push_back("cD");
d.run(d.vars_Derived);
return 0;
}
Is that the result you want to get?
class Base
{
protected:
using vars_type = std::vector<std::string>;
private:
vars_type vars_Base;
protected:
virtual vars_type& get_vars() {
return vars_Base;
}
public:
void push_back(const std::string& str) {
get_vars().push_back(str);
}
void run()
{
for (auto int_vars_it : get_vars()) {
std::cout << int_vars_it << " ";
}
}
};
class Derived : public Base
{
private:
vars_type vars_Derived;
protected:
vars_type& get_vars() override {
return vars_Derived;
}
public:
///Here are other functions only known to Derived, not Base
};
int main(int argc, char* argv[])
{
Base b;
b.push_back("aB");
b.push_back("bB");
b.push_back("cB");
b.run(); // prints aB bB cB
std::cout << std::endl;
Derived d;
d.push_back("aD");
d.push_back("bD");
d.push_back("cD");
d.run(); // prints aD bD cD
return 0;
}
If so then the explanation is next: there is no such thing as a "virtual variable", but there are virtual functions. You can use virtual functions as "internal accessors" for your member variables. Although, Derived class contains both vars_Base and vars_Derived, get_vars() lets you override access to appropriate instance of vars.
Hope you'll find it helpful.
You can make use of virtual functions to solve your problem, without the use for generics.
Here is a solution using virtual functions (applied to your sample code) :
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
class Base
{
protected:
void read(std::vector<std::string>);
public:
virtual void run() { read(vars_Base); }
std::vector<std::string> vars_Base;
};
void Base::read(std::vector<std::string> int_vars)
{
for (auto int_vars_it : int_vars)
{
std::cout << int_vars_it << "\n";
}
}
class Derived : public Base
{
protected:
public:
void run() override { read(vars_Derived); }
std::vector<std::string> vars_Derived;
///Here are other functions only known to Derived, not Base
};
int main()
{
Base b;
b.vars_Base.push_back("aB");
b.vars_Base.push_back("bB");
b.vars_Base.push_back("cB");
b.run();
Derived d;
d.vars_Derived.push_back("aD");
d.vars_Derived.push_back("bD");
d.vars_Derived.push_back("cD");
d.run();
return 0;
}
This solution allows to encapsulate vars_Base and vars_Derived inside the classes.
Hope this helps.

gmock - mocking non-virtual method of the derived class

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.

Mock non-virtual method giving compilation error

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);
}