C++ Google Mock - EXPECT_CALL() - expectation not working when not called directly - c++

I'm still pretty new to Google Mock so learning as I go. I've just been adding some unit tests and I've run into an issue where I can't get ON_CALL() to correctly stub a method called from within a method.
The following code outlines what I have;
class simpleClass
{
public:
bool simpleFn1() { return simpleFn2(); }
virtual bool simpleFn2() { return FALSE; }
}
In my unit test I have:
class simpleClassMocked : public simpleClass
{
private:
MOCK_METHOD0(simpleFn2, bool());
}
class simpleClassTests : public ::testing::Test
{
}
TEST_F(simpleClassTests, testSimpleFn2)
{
shared_ptr<simpleClassMocked> pSimpleClass = shared_ptr< simpleClassMocked >(new simpleClassMocked());
ON_CALL(*pSimpleClass, simpleF2()).WillByDefault(Return(TRUE));
// This works as expected - simpleFn2() gets stubbed
pSimpleClass->simpleFn2();
// This doesn't work as expected - when simpleFn1 calls simpleFn2 it's not the stubbed expectation???
pSimpleClass->simpleFn1();
}
I figure I must be missing something obvious here, can anyone help? Thanks!

you'll have to Mark the method as virtual and add a corresponding MOCK function in the simpleClassMocked class
class simpleClass
{
public:
virtual bool simpleFn1() { return simpleFn2(); }
virtual bool simpleFn2() { return FALSE; }
}
Also, you need to put the Mock methods in the public area
class simpleClassMocked : public simpleClass
{
public:
MOCK_METHOD0(simpleFn2, bool());
MOCK_METHOD0(simpleFn1, bool());
}
It will work now

Related

Using dependency injection and mocking it with gmock

I have implemented a Dependency Injection pattern in my code. I did that to be able to mock a service using gmock. The DI implementation works in production code, however, I am having trouble with my test setup. When using the EXPECT_CALL macro, I get "expression must have class type" error. I believe this is related to the way I designed the dependency, but I can't find an alternative solution (lack of experience). I have browsed previous threads on similar issues, but none helped. Would you be kind to take a look at the code below and hint possible workarounds (simplified code example using a Car-Engine interface)?
// Engine interface class with pure virtual functions
class IEngine
{
public:
virtual ~IEngine() = default;
virtual void start() = 0;
virtual void stop() = 0;
};
// A V8Engine class implementing this interface
class V8Engine : public IEngine
{
public:
void start() override { std::cout << "V8 Engine started\n"; };
void stop() override { std::cout << "V8 Engine stopped\n"; };
};
// Car.h file
class Car
{
public:
Car(IEngine *engineService);
void Drive();
private:
IEngine* mEngine = nullptr;
};
// Car.cpp file
Car::Car(IEngine* engineService)
: mEngine(engineService)
{
if (mEngine == nullptr)
{
throw std::invalid_argument("service must not be null");
}
}
void Car::Drive()
{
mEngine->start();
mEngine->stop();
}
I would like to be able to mock the engine implementation and instead of using a "real V8Engine", utilize the mock. Here is how I set up my test:
class MockEngine : public IEngine
{
public:
MOCK_METHOD(void, start, (), (override));
MOCK_METHOD(void, stop, (), (override));
};
TEST(TestCarClass, TestCarWithMockEngine)
{
IEngine *mockEngine = new MockEngine;
Car carUnderTest(mockEngine);
carUnderTest.Drive();
EXPECT_CALL(mockEngine, start()); // This is the part where I get the error due to invalid mockEngine setup
}
EXPECT_CALL expects mock object as first parameter, you pass reference to mock.
either use *mockEngine:
TEST(TestCarClass, TestCarWithMockEngine)
{
IEngine *mockEngine = new MockEngine;
Car carUnderTest(mockEngine);
EXPECT_CALL(*mockEngine, start());
carUnderTest.Drive();
}
or avoid allocation directly:
TEST(TestCarClass, TestCarWithMockEngine)
{
MockEngine mockEngine;
Car carUnderTest(&mockEngine);
EXPECT_CALL(mockEngine, start());
carUnderTest.Drive();
}

TEST_F in google mock giving error

It's a simple example to use google mocking along with fixtures. I am trying to setup up and learn google mock on Xcode and wrote following code
using ::testing::Return;
class Shape {
public:
virtual int calculateArea() = 0;
virtual std::string getShapeColor() = 0; // this interface must have been used by some other class under test
};
// Mock class for Shape
class MockShape : public Shape{
public:
MOCK_METHOD0(calculateArea, int());
MOCK_METHOD0(getShapeColor, std::string());
};
// class under test
class Show{
public:
Show() : printFlag(false), isColorValid(false) {}
void printArea(Shape *shape) {
if (shape->calculateArea() <= 0)
printFlag = false;
else
printFlag = true;
}
void printColor(Shape *shape) {
if (shape->getShapeColor().compare("black"))
isColorValid = true;
else
isColorValid = false;
}
bool printFlag;
bool isColorValid;
};
// Test fixture for class under test
class FixtureShow : public ::testing::Test{
public:
void SetUp(){}
void TearDown(){}
void SetUpTestCase(){}
void TearDownTestCase(){}
Show show; // common resources to be used in all the test cases
MockShape mockedShape;
};
TEST_F(FixtureShow, areaValid) {
EXPECT_CALL(mockedShape, calculateArea()).WillOnce(Return(5));
show.printArea(&mockedShape);
EXPECT_EQ(show.printFlag, true);
}
"TEST_F(FixtureShow, areaValid) " is giving error "Call to non static member function without an object argument". Can anyone help me why am I getting this error?
SetUpTestCase() and TearDownTestCase() are meant to be declared as static member functions. You can also delete them unless you are planning to put some code in.

Set expectation in Google mock using pointer to the mock object

I request your inputs/suggestions/help regarding setting expectation to a mock method using the pointer to the mock object.
The stack is in CPP and the application creates an object of the stack class using new operator.
In the unit test, expectations need to be set on the mock object created in the source code.
Thanks a lot in advance.
Please find the code snippet below:
StackBT.h
class StackBT
{
MOCK_METHOD0(registerCallbacks, void());
MOCK_METHOD2(...)
MOCK_METHOD4(...)
}
ApplicationBT.h:
class ApplicationBT
{
public:
ApplicationBT() : mpoStackBT(new StackBT())
void init()
{
mpoStackBT->registerCallbacks();
}
friend class TestApplicationBT;
StackBT* mpoStackBT;
}
TestApplicationBT.h
class TestApplicationBT : public ::testing::Test
{
protected:
virtual void SetUp ()
{
ptrApplicationBT = new ApplicationBT();
}
void TearDown()
{
delete ptrApplicationBT;
}
public:
TestApplicationBT ()
{
}
~TestApplicationBT ()
{
ptrApplicationBT = NULL;
}
scoped_ptr<ApplicationBT> ptrApplicationBT;
};
TEST_F(TestApplicationBT, TEST_FUNC_CALL_IN_MOCK_CREATED_INSIDE_ApplicationBT_USING_NEW)
{
EXPECT_CALL(ptrApplicationBT->mpoStackBT, registerCallbacks()).Times(1);//Need to pass the object instead of the reference to StackBT
ptrApplicationBT->init();
}

How to test method in google test, using std::function?

I would like to test method "methodToTest" in class A:
typedef std::function F_global;
struct A
{
F_global m_F_global;
A(F_global m_F_global) : p_F_global(m_F_global) {}
void methodToTest()
{
m_F_global(5);
}
};
I have got a mock class:
class RunMock
{
public:
MOCK_METHOD1(run, void (int));
};
Below I have got a test case:
class TestClass : public testing::Test
{
protected:
void SetUp();
std::unique_ptr<A> m_aa;
std::unique_ptr<RunMock> m_runMock;
};
void UecSimplePortTestSuite::SetUp()
{
m_aa = make_unique<A>(m_runMock->run);//IT DOESN'T WORK I DON'T KNOW HOW TO FORWARD A METHOD run from RunMock to constructor
}
TEST_F(UecSimplePortTestSuite, testForwardMessage)
{
EXPECT_CALL(*m_runMock, run(_));
m_aa->methodToTest();
}
Generally I don't know how transfer a method "run" from Mock class "RunMock" in "UecSimplePortTestSuite::SetUp()". I would like to do this, because
I would like to "EXPECT_CALL(*m_runMock, run(_));" in UecSimplePortTestSuite.testForwardMessage to test "methodToTest()".
I think that good idea could be to use lmbda, std::boost::bind or something like this.
You can pass a lambda to the constructor of A in the SetUp() :
m_runMock.reset( new RunMock );
m_aa.reset( new A( [&](int value){ m_runMock->run(value); } );
This :
m_runMock->run
is not going to do what you thing, and it is a compilation error. You can read this parashift QA and here how to use pointer to member function.

Unit Testing Moq not passing through method when virtual

Hi say I have some code like:
public class Class1
{
public int MyMethod()
{
return MyOtherMethod();
}
public virtual int MyOtherMethod()
{
return 1;
}
}
Ok, this doesn't do much of relevance but this is just for a simple example.
I then create a new test:
[TestMethod]
public void TestMethod1()
{
var t = new Mock<Class1>();
var w = t.Object.MyMethod();
}
Could someone please tell me why the code runs through the called method MyOtherMethod when it's not designated as virtual but when you make it virtual the test code refuses to go through that method?
You should setup the virtual method before you calling MyMethod:
t.Setup(c => c.MyOtherMethod()).Return(1);