Google Test on a local function that calls another function - c++

I have a class that I want to test.
class Myclass {
virtual int functionA (int x) {
if (x==1) {
functionB();
return 1;
}
else return 0;
}
virtual void functionB() {
// do some logic
functionC();
printf ("functionB \n"};
}
virtual void functionC() {
// do some logic
printf ("functionC \n"};
}
}
I setup a Mock class:
class MockMyClass : public Myclass {
MOCKMETHOD1(functionA, int(int x));
MOCKMETHOD0(functionB, void());
MOCKMETHOD0(functionC, void());
}
My test case in test class:
class MyTesting : public testing::Test {
virtual void SetUp(){
testObj = new MyClass();
testMock = new MockMyClass();
}
virtual void Teardown() {
delete testObj;
delete testMock;
}
}
MyClass * testObj;
MockMyClass * testMock;
TEST_F (MyClass, Test1){
EXPECT_CALL (testMock, functionB());
testObj->functionA()
}
TEST_F (MyClass, Test2){
EXPECT_CALL (testMock, functionC());
testObj->functionB()
}
TEST_F (MyClass, Test3){
EXPECT_CALL (testMock, functionC());
testObj->functionC()
}
Basically, I need to run the functionA -> functionB -> functionC.
How can write Test1 such that when have expect call of functionB, it doesn't "go further" into B and requires another expect call of function C.
In other words, how can write a Test1 such that whatever logic in functionB will be tested in Test2 and further in Test3 and Test1 just expect a call of functionB.

TEST_F (MyClass, Test1) {
InSequence seq;
EXPECT_CALL (MockMyClass, functionB());
EXPECT_CALL (MockMyClass, functionC());
testObj->functionA(1);
}
InSequence
Your example will not compile, functionA requires arg and missing semicolons.

Wrong use of inheritance is main problem here.
If your class under test is same as mock class then this should be obvious something wrong is here.
Note that here:
virtual void SetUp() {
testObj = new MyClass();
testMock = new MockMyClass();
}
there is no dependency between testObj and testMock. So Question is how testObje can impact state of testMock? It can't!
So basically problem is your code design of production code (code under test).
Since logic of this class has been obfuscated I have no clues how I could fix your code properly. I'm guessing it should be something like this:
class ISomeDependency {
public:
virtual int functionA(int x) = 0;
};
//---------
class Myclass {
public:
Myclass(ISomeDependency& dep)
: mDep { dep }
{
}
void functionB()
{
if (mDep.function(1) > 5) {
functionC();
}
}
void functionC()
{
}
private:
ISomeDependency& mDep;
};
class MyclassTest : public ::testing::Test {
void checkMyClassIsInStateX()
{
ASSERT_EQ(myClass.getX(), ...);
}
public:
MockSomeDependency mock;
Myclass myClass { mock };
};
TEST_F(MyclassTest, functionBCallsDependencyWithOneAndChangesStateToX)
{
EXPECT_CALL(mock, functionA(1)).WillOnce(Return(4));
myClass.functionB();
checkMyClassIsInStateX();
}

Related

Factory Pattern w/ Gmock

I have a interface where I am using the factory pattern to create an instance of the object and store it in a unique_ptr. I also have a MockInterface which I would like to use in my tests to not call the actual production code. However when I run my tests the production interface is called instead of the mock. What am I doing wrong??
Interface.hpp
class Interface
{
Interface() {};
virtual ~Interface() = default;
virtual int foo() = 0;
virtual int bar() = 0;
static std::unique_ptr<Interface> create();
};
Interface.cpp
#include "Interface.hpp"
#include "Impl.hpp"
std::unique_ptr<Interface> Interface::create()
{
return std::unique_ptr<Interface> { new Impl() };
}
Impl.hpp
class Impl : public Interface
{
Impl() {};
~Impl() {};
virtual int foo();
virtual int bar();
};
Impl.cpp
#include "Interface.hpp"
#include "Impl.hpp"
int Impl::foo()
{
return 2;
}
int Impl::bar()
{
return 2;
}
class MockInterface : public Interface
{
MockInterface() {};
~MockInterface() {};
MOCK_METHOD(int, foo, (), (override));
MOCK_METHOD(int, bar, (), (override));
}
lib.cpp
#include "Interface.hpp"
class Foo
{
public:
Foo() { inst = Interface::create(); }
virtual ~Foo() = default;
void some_function();
private:
std::unique_ptr<Interface> inst;
}
void Foo::some_function()
{
int foo_ret = inst->foo();
int bar_ret = inst->bar();
}
test.cc
std::unique_ptr<Interface> Interface::create()
{
std::unique_ptr<MockInterface> mock { new MockInterface() };
EXPECT_CALL(*mock, foo()).Times(1);
EXPECT_CALL(*mock, bar()).Times(1);
return mock;
}
TEST_F(fixture, test_foo)
{
// This will pass but I will get an error "mock object never deleted"
// Will also leave my terminal in a bad state
Foo *obj = new Foo();
obj->some_function();
// This will fail also leaving my terminal in a bad state
Foo obj2;
obj2.some_function();
}
some_function() calls Interface::create(), which has not been mocked, so it's still going to give you back a unique pointer pointing to an Impl object, not a MockInterface object.
To solve this you can either mock out Interface::create to have it return your mocked object, or have some_function receive a pointer/reference to Interface as a parameter instead of calling Interface::create itself. Then just pass it your mocked object.
The simplest way to mock the create function is to just redefine it for your tests. Exclude Interface.cpp from your test program since the function can only be defined once
std::unique_ptr<Interface> Interface::create()
{
std::unique_ptr<MockInterface> mock { new MockInterface() };
EXPECT_CALL(*mock, foo()).Times(1);
return mock;
}
TEST_F(fixture, test_foo)
{
some_function();
}
To provide different implementations for each test you can do something like this:
std::function<std::unique_ptr<Interface>()> creator;
std::unique_ptr<Interface> Interface::create()
{
return creator();
}
TEST_F(fixture, test_foo)
{
creator = []() {
std::unique_ptr<MockInterface> mock { new MockInterface() };
EXPECT_CALL(*mock, foo()).Times(1);
return mock;
};
// Will call Interface::create which will call creator()
some_function();
}

How to test a class method that instantiates non mocked classes in C++?

This is my first experience in UniTesting and it's giving me headaches when developing the tests, if you could help it would be really nice.
I have in my program something like this:
class Baseclass
{
public:
Baseclass(Class2 arg) { mProperty = arg};
void doSomething();
void doSomethingElse();
private:
Class2 mProperty;
}
class Class1
{
public:
bool doClass1Stuff();
...
}
class Class2
{
public:
bool doClass2Stuff();
Class1* getClass1(){return mClass1;};
...
private:
Class1* mClass1;
}
I'm using GoogleTest and gMock to write the tests:
class MockClass1 : public Class1
{
public:
MOCK_METHOD(bool, doClass1Stuff,());
};
class MockClass2 : public Class2
{
public:
MOCK_METHOD(MockClass1*, getClass1,());
}
I can't solve the problem when testing a method of BaseClass that do something like this:
double BaseClass::methodToTest()
{
Class1* myObject = dynamic_cast<Class1*>(mProperty.getClass1());
if(myObject.doClass1Stuff())
{
//The rest of the code
}
return returnValue;
}
In the code below: when calling BaseClass::methodToTest(), mProperty.getClass1() and doClass1Stuff() are calling real methods instead of mock methods.
TEST(TestSuite1, TestName1){
MockClass1 * myMockObject1 = new MockClass1;
MockClass2 * myMockObject2 = new MockClass2;
BaseClass * testObject = new BaseClass(myMockClass2Object);
ON_CALL(myMockObject1,doClassic1Stuff()).WillByDefault(Return(true));
ON_CALL(myMockObject2, getClass1()).WillByDefault(Return(myMockObject1));
auto var = testObject.methodToTest();
ASSERT_EQ( 0.0, var);
}
How can I make BaseClass call mock methods? Should I modify the source code to test it?
I would appreciate any information you can give me. Thanks.
You have object slicing with your BaseClass usage with mock, you need something like:
class Baseclass
{
public:
Baseclass(std::unique_ptr<Class2> arg) mProperty(std::move(arg)) {}
void doSomething();
void doSomethingElse();
double methodToTest()
{
Class1* myObject = mProperty->getClass1();
if (myObject->doClass1Stuff())
{
//The rest of the code
}
return returnValue;
}
private:
std::unique_ptr<Class2> mProperty;
};
And your TEST, should be similar to:
TEST(TestSuite1, TestName1){
MockClass1 myMockObject1;
ON_CALL(myMockObject1, doClassic1Stuff()).WillByDefault(Return(true));
auto myMockObject2 = std::make_unique<MockClass2>();
ON_CALL(*myMockObject2, getClass1()).WillByDefault(Return(myMockObject1));
BaseClass testObject(std::move(myMockClass2Object));
// Note: myMockObject2 is nullptr now, as moved, you no longer can use it for ON_CALL
auto var = testObject.methodToTest();
ASSERT_EQ( 0.0, var);
}

How to use shared_ptr to supply mock object from outside?

I want to test an app Thud, which will use a resource Foo. It will not own a concrete object but will have a pointer to a abstract resource interface (IFoo here). In production I will supply it with the actual resource implementation (FooImpl) whereas for unit test I want to send a pointer to a mock resource. How should I do this ? I've tried to write the least code just to get to point,
class IFoo
{
public:
virtual bool Foo(bool) = 0;
};
class FooImpl : public IFoo
{
public:
bool Foo(bool b) override
{
return b;
}
};
class FooMock : public IFoo
{
public:
MOCK_METHOD1(Foo, bool(bool));
};
class ThudTest : public ::testing::Test
{
protected:
virtual void SetUp() {
//foo.reset(&mock); //line#1
foo = &mock; //line#2
}
FooMock mock;
//std::shared_ptr<IFoo> foo; //line#3
IFoo* foo; //line#4
};
class Thud
{
//std::shared_ptr<IFoo> fooPtr; //line#5
IFoo* fooPtr; //line#6
public:
/*Thud(std::shared_ptr<IFoo> fooPtr_) : fooPtr{ fooPtr_ }
{}*/ //line#7
Thud(IFoo* fooPtr_) : fooPtr{ fooPtr_ }
{} //line#8
bool thud1(bool b)
{
return fooPtr->Foo(b);
}
};
TEST_F(ThudTest, fooFalse)
{
bool b = false;
EXPECT_CALL(mock, Foo(b)).Times(1).WillOnce(Return(false));;
Thud thud(foo);
EXPECT_FALSE(thud.thud1(b));
}
TEST_F(ThudTest, fooTrue)
{
bool b = true;
EXPECT_CALL(mock, Foo(b)).Times(1).WillOnce(Return(true));;
Thud thud(foo);
EXPECT_TRUE(thud.thud1(b));
}
int main(int argc, char** argv) {
// The following line must be executed to initialize Google Mock
// (and Google Test) before running the tests.
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
So for completion I've has an overloaded constructor that takes not arguement but will do the following,
Thud():fooPtr {std::make_shared<FooImpl>()}
{}
to get the real implementation in production.
But now how do I make the pointer point to the mock object. As you can see, I'm using GMock framework here. How to achieve this ?
If I comment out line #2,4,6 & 8 which uses a plain old raw pointer and uncomment and use line #1,3,5 & 7 (using the shared_ptr in question here) instead, it crashes with heap corruption after the first test case.
It works perfectly with this raw pointer.
You cannot do foo.reset(&mock), since then mock has two owners: its automatic storage duration, plus the shared pointer foo. Memory corruption FTW.
You should simply allocate the FooMock dynamically and pass it in when creating the Thud instance being tested:
class ThudTest : public ::testing::Test
{
protected:
virtual void SetUp() {
foo = std::make_shared<FooMock>();
}
std::shared_ptr<FooMock> foo;
};
You won't even need the mock member any more. Note that I've changed the type of foo to know about FooMock, so that you can access that type. If you really want foo to remain mock-unaware, do it like this:
class ThudTest : public ::testing::Test
{
protected:
virtual void SetUp() {
mock = std::make_shared<FooMock>();
foo = mock;
}
std::shared_ptr<FooMock> mock;
std::shared_ptr<IFoo> foo;
};
However, this should not be necessary, since std::shared_ptr<FooMock> is implicitly convertible to std::shared_ptr<IFoo>.
With:
class Thud
{
std::shared_ptr<IFoo> fooPtr;
public:
Thud(std::shared_ptr<IFoo> fooPtr_) : fooPtr{ fooPtr_ }
{}
bool thud1(bool b)
{
return fooPtr->Foo(b);
}
};
Your tests can become (I remove the Feature):
TEST(ThudTest, fooFalse)
{
auto mock = std::make_shared<FooMock>()
bool b = false;
EXPECT_CALL(*mock, Foo(b)).Times(1).WillOnce(Return(false));;
Thud thud(mock);
EXPECT_FALSE(thud.thud1(b));
}
TEST(ThudTest, fooTrue)
{
auto mock = std::make_shared<FooMock>()
bool b = true;
EXPECT_CALL(*mock, Foo(b)).Times(1).WillOnce(Return(true));;
Thud thud(mock);
EXPECT_TRUE(thud.thud1(b));
}
In my solution a needed to use shared_ptr<IFoo> to add it to collection in other tested class and I figured out to use a referecne ;). Then I tried with NiceMock<IFoo> and StrictMock<IFoo> also and it worked.
using namespace testing;
using namespace std;
class ThudTest : public Test {
public:
shared_ptr<FooMock> fooPtr_ = make_shared<FooMock>();
// shared_ptr<StrictMock<FooMock>> fooPtr_ = make_shared<StrictMock<FooMock>>();
FooMock& mock = *fooPtr_;
// StrictMock<FooMock>& mock= *fooPtr_;
bool thud1(bool b) {
return fooPtr_->Foo(b);
}
};
And tests can be writen without *:
TEST_F(ThudTest, fooFalse) {
bool b = false;
EXPECT_CALL(mock, Foo(b)).Times(1).WillOnce(Return(false));
EXPECT_FALSE(thud1(b));
}
TEST_F(ThudTest, fooTrue) {
bool b = true;
EXPECT_CALL(mock, Foo(b)).Times(1).WillOnce(Return(true));
EXPECT_TRUE(thud1(b));
}

How to mock this class

class A
{
public:
void doFirstJob()
{
// Do first Job.
}
}
class B : public A
{
public:
virtual void doSecondJob()
{
// Do Second Job.
}
}
class C
{
public:
void doSomething() {
b->doFirstJob();
b->doSecondJob();
}
private:
B* b;
}
Now I should write unit test code for class C, then I'll write a mock for class B, but the problem is how to mock the method doFirstJob().
Bluntly, I want know how to mock the non-virtual method of the parent class???
Can any one help me ??
Typemock Isolator++ supports mocking non virtual methods of a parent class (same as faking a method of the class under test).
See following example:
class A
{
public:
int doFirstJob()
{
return 0;
}
};
class B : public A
{
};
class C
{
public:
int doSomething()
{
return b->doFirstJob();
}
void setB(B* to)
{
b = to;
}
private:
B* b;
};
In the test You create a fake of B -> change the behavior of doFirstJob to return 3 -> continue with your test as you would normally write it.
TEST_CLASS(NonVirtualMethod)
{
public:
TEST_METHOD(NonVirtualMethodTestOfBaseClass)
{
B* fakeB = FAKE<B>();
WHEN_CALLED(fakeB->doFirstJob()).Return(3);
C c;
c.setB(fakeB);
int first = c.doSomething();
Assert::AreEqual(3,first);
}
}
You can find more examples here.

gmock: Why isn't EXPECT_CALL detecting the function call in my test?

The text "callback called" from Callback() prints to console, but gmock fails the test saying that no callback happened. What am I doing wrong?
class MyClass
{
public:
MyClass() { };
virtual ~MyClass() { };
void Callback() { printf("callback called\n"); };
};
class MyClassMock : public MyClass
{
public:
MOCK_METHOD0(Callback, void());
};
class Caller
{
public:
Caller(MyClass *myClass) { m_myClass = *myClass; };
void Call() { m_myClass.Callback(); };
private:
MyClass m_myClass;
};
TEST(BasicTest, Positive)
{
MyClassMock mock;
EXPECT_CALL(mock, Callback()).Times(1);
Caller caller(&mock);
caller.Call();
}
Your
void Callback();
method is not declared virtual. So you can't mock it that way with a simple derived mock class.
To cite from the google-mock documentation
Google Mock can mock non-virtual functions to be used in what we call hi-perf dependency injection.
In this case, instead of sharing a common base class with the real class, your mock class will be unrelated to the real class, but contain methods with the same signatures.
The consequence is you have to realize this with a template. There's a concise example given at the documentation section linked from above.
Trying to "translate" their sample to your case, it should look like
class MyClass {
public:
MyClass() { };
virtual ~MyClass() { };
void Callback() { printf("callback called\n"); };
};
class MyClassMock {
public:
MOCK_METHOD0(Callback, void());
};
template<class T>
class Caller {
public:
Caller(T& myClass) : m_myClass(myClass) {}
void Call() { m_myClass.Callback(); }
private:
T& m_myClass;
};
TEST(BasicTest, Positive) {
MyClassMock mock;
EXPECT_CALL(mock, Callback()).Times(1);
Caller<MyClassMock> caller(mock);
caller.Call();
}