1      初识gmock

1.1      什么是Mock

便捷的模拟对象的方法。

1.2      Google Mock概述

google mock是用来配合google test对C++项目做单元测试的。它依赖于googletest

Google Mock(简称gmock)是Google在2008年推出的一套针对C++的Mock框架,它灵感取自于jMockEasyMockharcreat。它提供了以下这些特性:

  • 轻松地创建mock类
  • 支持丰富的匹配器(Matcher)和行为(Action)
  • 支持有序、无序、部分有序的期望行为的定义
  • 多平台的支持

1.3      获取、编译google mock

见gtest,gtest项目里就包含gmock

1.4      最简单的例子

class MockFoo: public FooInterface {
public:
MOCK_METHOD0(getArbitraryString, std::string());
}; using ::testing::Return; int main(int argc, char** argv) {
::testing::InitGoogleMock(&argc, argv); string value = "Hello World!";
MockFoo mockFoo;
EXPECT_CALL(mockFoo, getArbitraryString()).Times().
WillOnce(Return(value));
string returnValue = mockFoo.getArbitraryString();
cout << "Returned Value: " << returnValue << endl; return EXIT_SUCCESS;
}

2      典型的流程

通过上述的例子,已经可以看出使用Mock类的一般流程如下:

  • 引入你要用到的Google Mock名称. 除宏或其它特别提到的之外所有Google Mock名称都位于*testing*命名空间之下.
  • 建立模拟对象(Mock Objects).
  • 可选的,设置模拟对象的默认动作.
  • 在模拟对象上设置你的预期(它们怎样被调用,应该怎样回应?).

2.1      自定义方法/成员函数的期望行为

在单元测试/主程序中使用这个Mock类中的方法时最关键的就是对期望行为的定义。

对方法期望行为的定义的语法格式如下:

EXPECT_CALL(mock_object, method(matcher1, matcher2, ...))
.With(multi_argument_matcher)
.Times(cardinality)
.InSequence(sequences)
.After(expectations)
.WillOnce(action)
.WillRepeatedly(action)
.RetiresOnSaturation();

解释一下这些参数(虽然很多我也没弄明白):

  • 第1行的mock_object就是你的Mock类的对象
  • 第1行的method(matcher1, matcher2, …)中的method就是你Mock类中的某个方法名,比如上述的getArbitraryString;而matcher(匹配器)的意思是定义方法参数的类型,我们待会详细介绍。
  • 第3行的Times(cardinality)的意思是之前定义的method运行几次。至于cardinality的定义,我也会在后面详细介绍。
  • 第4行的InSequence(sequences)的意思是定义这个方法被执行顺序(优先级),我会再后面举例说明。
  • 第6行WillOnce(action)是定义一次调用时所产生的行为,比如定义该方法返回怎么样的值等等。
  • 第7行WillRepeatedly(action)的意思是缺省/重复行为。

先举个例子来说明一下,后面有针对更为详细的说明:

EXPECT_CALL(mockTurtle, getX()).Times(testing::AtLeast()).
WillOnce(testing::Return()).WillOnce(testing::Return()).
WillRepeatedly(testing::Return())

这个期望行为的定义的意思是:

  • 调用mockTurtle的getX()方法
  • 这个方法会至少调用5次
  • 第一次被调用时返回100
  • 第2次被调用时返回150
  • 从第3次被调用开始每次都返回200

2.2      Matcher(匹配器)

Matcher用于定义Mock类中的方法的形参的值(当然,如果你的方法不需要形参时,可以保持match为空。),就是判断在调用这个函数时,入参的值是否符合预先设置的条件,就是一个预设的EXPECT_TRUE。

它有以下几种类型:

一般比较、浮点数的比较、字符串匹配、容器的匹配、成员匹配器、匹配函数或函数对象的返回值、指针匹配器、复合匹配器

具体参考原文吧https://www.cnblogs.com/welkinwalker/archive/2011/11/29/2267225.html

2.3      基数(Cardinalities)

基数用于Times()中来指定模拟函数将被调用多少次|

2.4      行为(Actions)

Actions(行为)用于指定Mock类的方法所期望模拟的行为:比如返回什么样的值、对引用、指针赋上怎么样个值,等等。 值的返回

Return()

让Mock方法返回一个void结果

Return(value)

返回值value

ReturnNull()

返回一个NULL指针

ReturnRef(variable)

返回variable的引用.

ReturnPointee(ptr)

返回一个指向ptr的指针

另一面的作用(Side Effects

Assign(&variable, value)

将value分配给variable

使用函数或者函数对象(Functor)作为行为

Invoke(f)

使用模拟函数的参数调用f, 这里的f可以是全局/静态函数或函数对象.

Invoke(object_pointer, &class::method)

使用模拟函数的参数调用object_pointer对象的mothod方法.

复合动作

DoAll(a1, a2, …, an)

每次发动时执行a1到an的所有动作.

IgnoreResult(a)

执行动作a并忽略它的返回值. a不能返回void.

复合行为举例:

    EXPECT_CALL(mockIParameter, getParamter(testing::_, testing::_)).Times().\
WillOnce(testing::DoAll(testing::Assign(&a, b), testing::Return()));

2.5      序列(Sequences)

默认时,对于定义要的期望行为是无序(Unordered)的,但有时候我们需要定义有序的(Ordered)的调用方式,即序列 (Sequences) 指定预期的顺序. 在同一序列里的所有预期调用必须按它们指定的顺序发生; 反之则可以是任意顺序.

3      Google Mock Cookbook

3.1      Mock protected、private方法

Google Mock也可以模拟protected和private方法,比较神奇啊(其实从这点上也可以看出,Mock类不是简单地继承原本的接口,然后自己把它提供的方法实现;Mock类其实就等于原本的接口)。

对protected和private方法的Mock和public基本类似,只不过在Mock类中需要将这些方法设置成public。

3.2      Mock 模版类(Template Class)

Google Mock可以Mock模版类,只要在宏MOCK*的后面加上T。

4      Gmock原理及源码分析

4.1      基本原理

EXPECT_CALL.WillOnce的核心工作: untyped_actions_.push_back(new Action<F>(action)); 也就是说它将返回值塞进了一个vector容器中。

MOCK_METHOD0的核心工作:this->UntypedInvokeWith(&args))->GetValueAndDelete();也就是说它从之前说的那个vector中取出返回的结果被删除。

参见:单元测试Mock之c++ gmock实现原理 https://www.jianshu.com/p/06f0a7d85877

4.2      源码分析

参见:Google Mock(Gmock)简单使用和源码分析——源码分析 https://blog.csdn.net/breaksoftware/article/details/51438033

5      参考文档

转一篇小亮同学的google mock分享https://www.cnblogs.com/welkinwalker/archive/2011/11/29/2267225.html

单元测试Mock之c++ gmock实现原理 https://www.jianshu.com/p/06f0a7d85877

Google Mock(Gmock)简单使用和源码分析——源码分析 https://blog.csdn.net/breaksoftware/article/details/51438033

官网,但我今天打不开官网了。

gmock使用、原理及源码分析的更多相关文章

  1. OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

    http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...

  2. ConcurrentHashMap实现原理及源码分析

    ConcurrentHashMap实现原理 ConcurrentHashMap源码分析 总结 ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对Ha ...

  3. HashMap和ConcurrentHashMap实现原理及源码分析

    HashMap实现原理及源码分析 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表, ...

  4. (转)ReentrantLock实现原理及源码分析

    背景:ReetrantLock底层是基于AQS实现的(CAS+CHL),有公平和非公平两种区别. 这种底层机制,很有必要通过跟踪源码来进行分析. 参考 ReentrantLock实现原理及源码分析 源 ...

  5. 【转】HashMap实现原理及源码分析

    哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景极其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...

  6. 【OpenCV】SIFT原理与源码分析:DoG尺度空间构造

    原文地址:http://blog.csdn.net/xiaowei_cqu/article/details/8067881 尺度空间理论   自然界中的物体随着观测尺度不同有不同的表现形态.例如我们形 ...

  7. 《深入探索Netty原理及源码分析》文集小结

    <深入探索Netty原理及源码分析>文集小结 https://www.jianshu.com/p/239a196152de

  8. HashMap实现原理及源码分析之JDK8

    继续上回HashMap的学习 HashMap实现原理及源码分析之JDK7 转载 Java8源码-HashMap  基于JDK8的HashMap源码解析  [jdk1.8]HashMap源码分析 一.H ...

  9. 【OpenCV】SIFT原理与源码分析:关键点描述

    <SIFT原理与源码分析>系列文章索引:http://www.cnblogs.com/tianyalu/p/5467813.html 由前一篇<方向赋值>,为找到的关键点即SI ...

随机推荐

  1. sencha touch list infinite 属性

    sencha touch list 1 默认每一项的高度会自动适应其内容. 2 当每一个 item 的高度都相同且不变时, 设置 itemHeight 为固定值 和 variableHeights 为 ...

  2. 013-PaymentUtils工具类模板

    package ${enclosing_package}; import java.io.UnsupportedEncodingException; import java.security.Mess ...

  3. Git使用总结(一):简介与基本操作

    一:简介 GIT是一个开源的分布式的版本控制系统,是由Linus 为了管理Linux内核开发而开发的一个开源的版本控制软件.相比SVN,它采用分布式版本库方式. 二:工作区,暂存区和版本库 左侧为工作 ...

  4. WPF的ComboBox简单用法

    1. ComboBox:下拉列表框 效果如下: 2.通常用法是 显示内容 + 选中内容后获得的值(也就是 Name = Value的键值对) 故以键值对来定义一个类,如: public class C ...

  5. type=file的change事件只能执行一次的解决方案

    最近帮朋友做个项目中遇到了type=file change事件只能执行一次的问题,度娘了一下,发现提供了各种解决方案,所以决定记录一下我的思考方向和最终解决方式. 起初帮朋友做个项目,项目中遇到上传文 ...

  6. [android] socket在手机上的应用

    1.手机助手 1.1 USB链接 可以读取手机的PID和VID,确定唯一的设备,可以给手机安装对应的驱动等 socket在固定端口通信 1.2 WIFI链接 pc在电脑在整个网段发送UDP数据包,手机 ...

  7. java 2018面试题-多线程汇总(含解答)

    学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行总结的,因此罗列了自己整理的多线程的问题,都是自己觉得比较经典和一些大企业面试会问 ...

  8. MD5加密+加盐

    了解: MD5加密,是属于不可逆的.我们知道正常使用MD5加密技术,同一字符,加密后的16进制数是不变的,自从出现彩虹表,对于公司内部员工来说,可以反查数据,获取不可能的权限,所以出现了salt算法. ...

  9. nexus3安装

    windows环境 1.下载nexus3 2.以管理员的方式打开命令行,建议打开服务管理界面,将这个服务设置为手动,步骤是:右键我的电脑-->服务-->nexus,然后点击设置手动启动 3 ...

  10. Creator4.2建模心得与技巧1——树的建立与跟随摄像机旋转

    Creator建模: 树一般在虚拟现实程序中都用面来实现,一种方法是通过两个面相互垂直成90度叠放在一起,另一种方法是让树面正对着视角一起旋转.这里主要说一下第二种方法. 主要思路:把树面一直正对着摄 ...