本文目的

gmock框架中自带Matcher只针对c++内置类型,如string,int,float等等,有时候无法满足项目要求,所以需要编写自己的Matcher对象。本文介绍如何使用gmock提供的Matcher宏快速编写自己的Matcher对象。

在测试重载的mock函数时,需要对Matcher做特别的封装,否则编译在查找重载函数时会出现歧义。

待测的对象

/** 文件Base.h**  Created on: 2011-10-1*      Author: bourneli*/#ifndef BASE_H_
#define BASE_H_#include <iostream>
#include <string>
using namespace std;class Param
{
public:int n1;double f1;
};class Dependence
{
public:virtual ~Dependence(){}virtual void show() const{cout << "I am a dependence of Foo" << endl;}virtual void show(const string& sSth) const{cout << "show: " << sSth << endl;}virtual void show(const Param& oParam) const{cout << oParam.n1 << endl;cout << oParam.f1 << endl;}
};/** 调用mock的对象*/
class Foo
{
public:void showVoid(const Dependence& oDep)const{oDep.show();}void showString(const Dependence& oDep, const string& sSth)const{oDep.show(sSth);}void showParam(const Dependence& oDep, const Param& oParam)const{oDep.show(oParam);}};#endif /* BASE_H_ */

类Dependece有三个重载函数:

  • void show(void)
  • void show(const string&)
  • void show(const Param&)

需要编写Dependence的Mock对象,用于测试类Foo,类Foo也分别有三个方法调用类Dependence不同的重载方法:

  • void showVoid(const Dependence&) --- 调用Dependence::show(void)
  • void showString(const Dependence&, const string&) --- 调用Dependence::show(const string&)
  • void showParam(const Dependence&, const Param&) --- 调用Dependence::show(const Param&)

还有一个类Param,这是一个自定义类,需要自己编写Param的Matcher对象。在这里,匹配逻辑为:如果两个Param对象的n1属性相同,那么就匹配。

编写自己的Matcher

编写自己的Matcher对象在gmock1.4后变得很容易,gmock框架为我们做了大部分的事情,看看如下的代码:

// custom matcher
MATCHER_P(ParamObjMatcher, oParam, "")
{const Param& op = (const Param&)arg;return op.n1 == oParam.n1;
}

只用了两行代码,就完成了自定义Matcher。MATCHER_P中的P代表参数,MATCHER_P其实应该写成“MATCHER_P1”,表示该matcher的构造函数只接受一个参数,同样的还有“MATCHER_P2、MATCHER_P3,..., MATCHER_P10”。宏的第一个参数代表该Matcher的类名,第二个参数代表Matcher的构造函数中的第一个参数,最后一个空内容的字符代表失败时输出信息,为空那么gmock会默认为你填写相关信息。arg是这个宏中的一个参数,代表被匹配的对象,在这里也就是“cosnt Param&”。Dependence类的mock对象如下,详细信息可以参见文章《gmock学习01---Linux配置gmock》。

/** 文件Dependence_mock.h**  Created on: 2011-10-1*      Author: bourneli*/#ifndef DEPENDENCE_MOCK_H_
#define DEPENDENCE_MOCK_H_#include <string>
#include "gmock/gmock.h"
#include "Base.h"// mock class
class DependenceMock: public Dependence
{
public:MOCK_CONST_METHOD0(show, void());MOCK_CONST_METHOD1(show, void(const string&));MOCK_CONST_METHOD1(show, void(const Param&));
};// custom matcher
MATCHER_P(ParamObjMatcher, oParam, "")
{const Param& op = (const Param&)arg;return op.n1 == oParam.n1;
}#endif /* DEPENDENCE_MOCK_H_ */

编写测试用例

mock的相关工作完成后,可以编写测试用例,首先看看测试用例的源代码,如下:

/** 文件DependenceUT.cpp**  Created on: 2011-10-1*      Author: bourneli*/#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "Dependence_mock.h"
#include "Base.h"using ::testing::MatchesRegex;
using ::testing::Matcher; TEST(DependenceTestSuite, ShowVoidTestCase)
{DependenceMock oMock;EXPECT_CALL(oMock, show());Foo oFoo;oFoo.showVoid(oMock);
}TEST(DependenceTestSuite, ShowStringTestCase)
{DependenceMock oMock;EXPECT_CALL(oMock, show(Matcher<const string&> // 注意这里 
         (MatchesRegex(".*error.*"))));Foo oFoo;oFoo.showString(oMock, "error happened in log");
}TEST(DependenceTestSuite, ShowParamTestCase)
{DependenceMock oMock;Param op;op.n1 = 1;op.f1 = 0.1;EXPECT_CALL(oMock, show(Matcher<const Param&>   // 注意这里(ParamObjMatcher(op))));Foo oFoo;op.f1 = 0.2; // 没有任何影响,因为只比较n1oFoo.showParam(oMock, op);
}

上面特别需要注意的地方是标有“注意这里”注释的代码,意义在于标记出该Matcher对象对应的类,这样编译器就可以根据类找到特定的重载函数。比如,MatchesRegex这个Matcher对象被Matcher<const string&>封装后,编译器就知道是调用void show(const string&)这个重载函数,同理对应我们的自定义Matcher ParamObjMatcher。这里还有一个小技巧,你可以在自定义Matcher中使用GTEST的相关断言,这样可以方便的验证自定义对象中的值。

结论

  1. 使用宏MATCHER_P快速编写自己的Matcher对象。
  2. 使用Matcher<T>指定Matcher对象对应的类型,告知编译器如何在重载函数查找特定的函数。
  3. 在自定义Matcher中使用gtest断言,可以方便验证mock函数的输入否和期望。

相关资料

  • Selecting Between Overloaded Functions http://code.google.com/p/googlemock/wiki/CookBook#Selecting_Between_Overloaded_Functions
  • GMock Build-In Matchers http://code.google.com/p/googlemock/wiki/CheatSheet#Matchers
声明:如有转载本博文章,请注明出处。您的支持是我的动力!文章部分内容来自互联网,本人不负任何法律责任。


本文转自bourneli博客园博客,原文链接:http://www.cnblogs.com/bourneli/archive/2012/09/08/2676990.html,如需转载请自行联系原作者

gmock学习02---编写自己的Matcher与如何让编译器识别被mock的重载函数相关推荐

  1. 编写自己的Matcher与如何让编译器识别被mock的重载函数

    本文目的 gmock框架中自带Matcher只针对c++内置类型,如string,int,float等等,有时候无法满足项目要求,所以需要编写自己的Matcher对象.本文介绍如何使用gmock提供的 ...

  2. C++模板学习02(类模板)(类模板语法、类模板与函数模板的区别、类模板中的成员函数创建时机、类模板对象做函数参数、类模板与继承、类模板成员函数类外实现、类模板分文件编写、类模板与友元)

    C++引用详情(引用的基本语法,注意事项,做函数的参数以及引用的本质,常量引用) 函数高级C++(函数的默认参数,函数的占位参数,函数重载的基本语法以及注意事项) C++类和对象-封装(属性和行为作为 ...

  3. Matlab GUI学习02:使用GUIDE开发图形界面程序

    pdf版本笔记的下载地址: Matlab GUI学习02_使用GUIDE开发图形界面程序(访问密码:3834) Matlab GUI学习02:使用GUIDE开发图形界面程序 GUIDE GUIDE简介 ...

  4. 微信小程序_基础组件学习02

    微信小程序_基础组件学习02 swiper组件 swiper是滑块容器,也就是手机端的轮播图. swiper组件有两部分组成swiper和swiper-item. swiper-item需要放在swi ...

  5. vue 如何生成一个dom元素_通过一个简单的示例学习如何编写Vue组件

    大家好,本篇文章我将带着大家一起学习如何编写自定义组件(Components),通过「vue基础」新手快速入门篇(一)这篇文章的学习,我们知道了 Vue 设计的目的就是为了方便我们创建基于组件UI的项 ...

  6. 基于OpenGL ES 的深度学习框架编写

    基于OpenGL ES的深度学习框架编写 背景与工程定位 背景 项目组基于深度学习实现了视频风格化和人像抠图的功能,但这是在PC/服务端上跑的,现在需要移植到移动端,因此需要一个移动端的深度学习的计算 ...

  7. java虚拟机预先加载哪些类_Java虚拟机JVM学习02 类的加载概述

    Java虚拟机JVM学习02 类的加载概述 类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对 ...

  8. MQL4编程初探:从零开始学习EA编写

    作为一名多年从事期货.外汇交易的投资者,拥有手工交易经验以及程序化交易经验和EA编写的经验,我想和大家分享一下如何从零开始学习EA编写. MQL4是MetaQuotes Language 4的简称,是 ...

  9. Python 学习 02 —— Python如何爬取数据

    文章目录 系列文章 二.Python 爬 虫 1.任务介绍 2.简介 3.基本流程 3.1.准备工作 3.1.1.分析页面 3.1.2.编码规范 3.1.3.导入模块 3.1.4.程序流程 3.2.获 ...

最新文章

  1. 浅析药品生产偏差管理进展及改进措施
  2. 在研究所工作是什么体验?和互联网公司比,你会怎么选?
  3. Gartner:2015年SIEM(安全信息与事件管理)市场分析
  4. 账号解锁_WOW正式服:周四新CD,解锁账号精华共享的正确姿势
  5. 如何使用nodejs代码在新浪微博上发布帖子
  6. 【动态规划】叠放箱子问题(ssl 1640)
  7. String 源码解析
  8. python批量下载网页文件夹_Python实现批量从不同的Linux服务器下载文件
  9. textarea怎么占满整个td_保健品为什么偏偏盯上老人?作为子女,应怎么面对老人狂买保健品...
  10. 消息中间件学习总结(9)——RocketMQ与kafka差异比较分析
  11. mac10.12 安装“任何来源”软件解决
  12. zabbix自定义监控之声音报警、用户和组权限
  13. 【人工智能】无人车系统仿真软件-PreScan
  14. 数据结构和算法的区别
  15. Git 配合G码云使用基本操作相关指令
  16. Vulnhub Typhoon-v1.02提权
  17. 土豆课外科技学习历程兼参加机器人大赛小记
  18. 华为p20nfc怎么复制门禁卡_新功能上线!你的手机NFC也可以当门禁卡使用
  19. 文件不能设置默认打开方式怎么办?
  20. 硬件加速 | 常用电路设计之PRBS伪随机码发生器的设计

热门文章

  1. SAP S4HANA 账户组的配置里'Int.Std.Grping'选项没勾选导致ABAP程序报错
  2. AI+IOT战火升级:未来人工智能抢人大战
  3. 看AI如何改变医疗影像学
  4. 人工智能(5)---一文解读人工智能创业的5大坑
  5. 人工智能可以自己编码?2022年这8个人工智能趋势值得关注!
  6. 神经科学如何影响人工智能?看DeepMind在NeurIPS2020最新《神经科学人工智能》报告,126页ppt...
  7. 量子计算和量子模拟研究获进展
  8. 从信息传递的视角看因果关系
  9. 深度学习奠基人特伦斯:美国学界已经找到了解释人工智能“黑盒子”的方法...
  10. 液态大脑与固态大脑——圣塔菲最新群体智能文集