前文我们已经讲解了gmock的基本语法,但是gmock只能mock虚函数,如果要mock非虚成员函数、静态成员函数、全局函数、重载函数、模板函数以及其他依赖库的函数时,gmock就很难实现。而cppmockfree可以支持这些函数的mock。
// gloabal function
int g_func(int a, int b)
{
return a + b;
}
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "cpp_free_mock.h"
#include
using namespace ::testing;
using namespace ::CppFreeMock;
namespace {
TEST(TestCppMockFree, CaseGlobalFunction)
{
auto mock = MOCKER(g_func);
EXPECT_CALL(*mock, MOCK_FUNCTION(_, _))
.WillOnce(Return(1))
.WillRepeatedly(Return(2));
EXPECT_EQ(1, g_func(1, 2));
EXPECT_EQ(2, g_func(12, 2));
mock->RestoreToReal();
EXPECT_EQ(14, g_func(12, 2));
}
class Adder {
public:
int add(int a, int b) const
{
return a + b;
}
};
TEST(TestCppMockFree, CaseStaticMemberFunction)
{
auto mock = MOCKER(&Adder::add);
// 针对类的成员函数,要注意占位符会多出一个,即第一个为this指针
// 而全局函数或者静态成员函数占位符个数等于实际参数个数
EXPECT_CALL(*mock, MOCK_FUNCTION(_, _, _))
.WillRepeatedly(Return(2));
Adder adder;
EXPECT_EQ(2, adder.add(1, 2));
EXPECT_EQ(2, adder.add(12, 2));
mock->RestoreToReal();
EXPECT_EQ(14, g_func(12, 2));
}
// static member function
class Printer {
public:
static std::string print(const std::string& str)
{
return str;
}
};
TEST(TestCppMockFree, CaseStaticMemberFunction)
{
auto mock = MOCKER(Printer::print);
EXPECT_CALL(*mock, MOCK_FUNCTION(_))
.WillRepeatedly(Return(std::string("mocker")));
EXPECT_STREQ("mocker", Printer::print("hello").c_str());
mock->RestoreToReal();
EXPECT_STREQ("hello", Printer::print("hello").c_str());
}
// overload function
class OverloadFunc {
public:
int foo() { return 0; }
int foo(int a) { return a;}
};
TEST(TestCppMockFree, CaseOverloadFunction)
{
OverloadFunc overload_func;
typedef int (OverloadFunc::*FuncType0)();
typedef int (OverloadFunc::*FuncType1)(int);
auto mock0 = MOCKER((FuncType0)&OverloadFunc::foo);
EXPECT_CALL(*mock0, MOCK_FUNCTION(_))
.WillRepeatedly(Return(2));
EXPECT_EQ(2, overload_func.foo());
auto mock1 = MOCKER((FuncType1)&OverloadFunc::foo);
EXPECT_CALL(*mock1, MOCK_FUNCTION(_, _))
.WillRepeatedly(Return(2));
EXPECT_EQ(2, overload_func.foo(1));
mock0->RestoreToReal();
mock1->RestoreToReal();
EXPECT_EQ(2, overload_func.foo(1));
mock0->RestoreToReal();
mock1->RestoreToReal();
EXPECT_EQ(0, overload_func.foo());
EXPECT_EQ(1, overload_func.foo(1));
}
// template class
template <class T>
class AdderT {
public:
T add(T a, T b) { return a + b; }
T add(T a, T b, T c) { return a + b + c; }
T adder(T a) { return a; }
};
TEST(TestCppMockFree, CaseTemplateFunction)
{
AdderT<int> adder;
// overload function
typedef int (AdderT<int>::*FuncType0)(int, int);
auto mock0 = MOCKER((FuncType0)&AdderT<int>::add);
EXPECT_CALL(*mock0, MOCK_FUNCTION(_, _, _))
.WillRepeatedly(Return(1));
EXPECT_EQ(1, adder.add(1, 2));
auto mock1 = MOCKER((FuncType1)&AdderT<int>::add);
EXPECT_CALL(*mock1, MOCK_FUNCTION(_, _, _, _))
.WillRepeatedly(Return(1));
EXPECT_EQ(1, adder.add(1, 2, 3));
mock0->RestoreToReal();
mock1->RestoreToReal();
EXPECT_EQ(3, adder.add(1, 2));
EXPECT_EQ(6, adder.add(1, 2, 3));
// normal function
auto mock2 = MOCKER(&AdderT<int>::adder);
EXPECT_CALL(*mock2, MOCK_FUNCTION(_, _))
.WillRepeatedly(Return(1));
EXPECT_EQ(1, adder.adder(2));
mock2->RestoreToReal();
EXPECT_EQ(2, adder.adder(2));
}
TEST(TestCppMockFree, CaseOtherLibrary)
{
auto mock = MOCKER(std::atoi);
EXPECT_CALL(*mock, MOCK_FUNCTION(_))
.WillRepeatedly(Return(22867));
EXPECT_EQ(22867, std::atoi("123"));
mock->RestoreToReal();
EXPECT_EQ(123, std::atoi("123"));
}
git clone https://github.com/gzc9047/CppFreeMock.git
注意在引入cppmockfree之前请务必引入gtest和gmock。如何引入,在我之前的文章中均有提及。
CXX = g++
CXXFLAGS = -Wall
LIBES = -lgtest -lgtest_main -lpthread
LPATH = -L/tools/googletest/1.11.0/build/lib # 替换成自己lib路径
HPATH = -I/tools/googletest/1.11.0/googletest/include/ # 替换成自己的include路径
HPATH += -I/xxx/cpp_freemock/ #替换成自己的include路径
UTEST_OBJD = hello_unit_test
hello_unit_test:hello_unit_test.cpp
${CXX} -o $@ $+ -I ../ ${HPATH} ${CXXFLAGS} ${LIBES} ${LPATH}
clean:
rm -rf *_unit_test