When I researched Gmock from Google, I've installed and built the project work well so far. But I have some concern about mocking a function. Now I have the following files:
<1> myGtest.h
#ifndef MYGTEST_H_
#define MYGTEST_H_
int test(int);
int function(int);
#endif /* MYGTEST_H_ */
<2> src_code.cpp
#include <stdio.h>
#include "myGtest.h"
int test(int a) {
printf("NOT overridden!\n");
return a;
}
int function(int a){
int x = test(a);
if(x == 0)
return 99;
else
return 0;
}
<3> myGtest_dummy.h
#ifndef MYGTEST_DUMMY_H_
#define MYGTEST_DUMMY_H_
#include "gmock/gmock.h"
#include "../myGtest/myGtest.h"
class myGtestMock
{
public:
myGtestMock(){};
~myGtestMock(){};
MOCK_METHOD1(test, int(int));
};
#endif /* MYGTEST_DUMMY_H_ */
<4> test_program.cpp
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "src/myGtest/myGtest.h"
#include "src/dummy/myGtest_dummy.h"
using testing::_;
using testing::Return;
using testing::InSequence;
using ::testing::AtLeast;
extern int function(int a);
extern int test(int a);
class BTest:public testing::Test{
public:
myGtestMock mock_test;
int __wrap_test(int a);
};
int BTest::__wrap_test(int a){
printf("overridden!\n");
return a;
}
TEST_F(BTest, CallMockTest) {
EXPECT_CALL(mock_test, test(0))
.WillOnce(Invoke(this, &BTest::__wrap_test));
function(99);
}
int main(int argc, char *argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Could you help me explain that: How can I mock the function int test(int)
? I'd like to expect that once TEST_F(BTest, CallMockTest)
is executed, the program call function(99);
. Then my mocking function int __wrap_test(int)
will be called instead of int test(int)
.
Thanks so much for the answer.
The key idea here is to realize that Mocks are objects mocking the behaviour of real objects. Meaning that you set expectations on them (ie: the number of times they are called, with which arguments, etc), and you simulate some actions using the mocks (ie: returning specific values, or changing some parameters, etc)
With your current implementation, when you call function(), it will still invoke the real implementation of test(). So your EXPECT_CALL will always fail. Ideally, test() should be part of an interface which you want to mock. Say:
class MyInterface{
public:
...
virtual int test(int a) = 0;
};
Note: for simplicity I will disregard the real implementation of MyInterface, since anyways we intend to by pass the real implementation using our mock.
Now, function() which is the function under test, should ideally be part of class. Changing your implementation a bit:
class MyClass{
....
int function(int a, MyInterface * interface){
int x = interface->test(a);
if(x == 0)
return 99;
else
return 0;
}
};
Now, using the second parameter of function(), you can pass the mock you created. But before that you need to define that you are mocking MyInterface:
class myGtestMock : public MyInterface{
....
};
Now, in your test file:
TEST_F(BTest, CallMockTest) {
myGtestMock myMockObj;
//Testing (x==0)
EXPECT_CALL(myMockObj, test(99))
.Times(1)
.WillOnce(Return(0)); //set the action
EXPECT_EQ(99,function(99, &myMockObj));
Mock::VerifyAndClear(&myMockObj); //to clear the expectation
//testing else
EXPECT_CALL(myMockObj, test(99))
.Times(1)
.WillOnce(Return(1)); //set the action
EXPECT_EQ(0,function(99, &myMockObj));
Mock::VerifyAndClear(&myMockObj); //to clear the expectation
}
There are many tricks you can learn from google mock CookBook