一、Mock的介绍
Mock,更确切地说应该是Mock Object。它究竟是什么?它有什么作用?
Mock的是仿真的意思,而google mock是用来配合google test对C++项目做单元测试的。比如当我们在单元测试、模块的接口测试时,当这个模块需要依赖另外一个/几个类,而这时这些个类还没有开发好,这时我们就可以定义Mock对象来模拟这些类的行为。
gmock提供了以下这些特性:
- 轻松地创建mock类
- 支持丰富的匹配器(Matcher)和行为(Action)
- 支持有序、无序、部分有序的期望行为的定义
- 多平台的支持
二、安装
gmock只能由Cmake编译,可以参考上一篇博客,我们在编译出了gmock,直接把它引入到工程中即可。
三、使用
3.1 定义一个虚函数的接口
FooInterface.h
#ifndef FOOINTERFACE_H_
#define FOOINTERFACE_H_
#include <string>
namespace seamless {
class FooInterface {
public:
virtual ~FooInterface() {}
public:
virtual std::string getArbitraryString() = 0;
};
} // namespace seamless
#endif // FOOINTERFACE_H_
3.2 用Google Mock来定义Mock类
FooMock.h
#pragma once
#ifndef MOCKFOO_H_
#define MOCKFOO_H_
#include <gmock/gmock.h>
#include <string>
#include "FooInterface.h"
namespace seamless {
class MockFoo : public FooInterface {
public:
MOCK_METHOD0(getArbitraryString, std::string()); // 模拟函数
};
} // namespace seamless
#endif // MOCKFOO_H_
我们定义使用gmock中的一个宏(Macro)MOCK_METHOD0来定义MockFoo中的getArbitraryString。Google Mock是需要你根据不同的形参个数来使用不同的Mock Method,我这里getArbitraryString没有函数,就是MOCK_METHOD0了,同理,如果是一个形参,就是MOCK_METHOD1了,依次往下。
3.3 开始仿真
main.cpp
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <iostream>
#include <string>
#include "FooMock.h"
using namespace seamless;
using namespace std;
using ::testing::Return;
int main(int argc, char** argv)
{
::testing::InitGoogleMock(&argc, argv);// 初始化一个Google Mock
string value = "Hello hello World!";
MockFoo mockFoo; // MOCK对象
EXPECT_CALL(mockFoo, getArbitraryString()).Times(1).WillOnce(Return(value)); // 设置期望的动作
string returnValue = mockFoo.getArbitraryString(); // 调用
cout << "Returned Value is : " << returnValue << endl;
system("pause");
return 0;
}
运行
这里提供一个github工程,已经包含gtest,gmock,可以下载使用
https://github.com/Shanlovana/DailyCode/tree/master/CppCodes
四、总结
通过上述的例子,已经可以看出使用Mock类的一般流程如下:
- 引入要用到的Google Mock名称.
- 建立模拟对象(Mock Objects).
- 设置模拟对象的默认动作
- 在模拟对象上设置你的预期(它们怎样被调用,应该怎样回应?).
参考: