GoogleTest中gMock的使用

news2024/9/26 3:19:46

      GoogleTest中的gMock是一个库,用于创建mock类并使用它们。
      当你编写原型或测试(prototype or test)时,完全依赖真实对象通常是不可行或不明智的(not feasible or wise)。模拟对象(mock object)实现了与真实对象相同的接口,但是需要你在运行时指定它将如何使用以及它应该做什么.在测试驱动开发(TDD, Test-Driven Development)中经常使用.
      当使用gMock时,首先,使用一些简单的宏来描述要mock的接口,它们将扩展到mock类的实现;接下来,你将创建一些mock对象,并使用直观的语法指定其期望和行为;然后练习(exercise)使用mock对象的code. gMock将在出现任何违反预期的行为时立即捕获(catch)它.

      MOCK_METHOD宏语法如下:MOCK_METHOD宏将生成定义

MOCK_METHOD(return_type,method_name, (args...));
MOCK_METHOD(return_type,method_name, (args...), (specs...));

      参数依次是:接口返回值类型、接口名、接口形参列表。可选的第四个参数specs...是以逗号分隔的限定符列表,接收限定符包括:const、override、noexcept、Calltype(calltype)、ref(qualifier). 如果参数没有适当地用圆括号括起来,那么参数中的逗号将阻止MOCK_METHOD正确地解析参数.
      MOCK_METHOD必须在mock类定义的public部分中使用,无论被mock的方法在基类中是public, protected, 还是private.

      在gMock中,使用EXPECT_CALL宏来设置对mock方法的期望,EXPECT_CALL宏语法如下:

EXPECT_CALL(mock_object,method_name(matchers...))

      创建一种期望(expectation),设置mock object的预期行为:第一个参数是mock object;第二个参数是mock object中的方法,两者用逗号分隔,如果有参数需要同时把参数传进去
      通过EXPECT_CALL来指定Mock Object的对应行为
      EXPECT_CALL必须在执行(exercises)mock对象的任何代码之前.
      参数matchers...是一个以逗号分隔的匹配器列表(list of matchers),对应于方法method_name的每个参数。期望仅适用于参数与所有匹配器匹配的method_name调用.如果省略(matchers...),则期望的行为就像每个参数的匹配器都是通配符匹配器(_)一样。
      宏的任何一种形式都可以后跟一些可选子句,这些子句提供有关期望的更多信息。以下可链接子句(chainable clauses)可用于修改期望,并且必须按以下顺序使用:

EXPECT_CALL(mock_object, method_name(matchers...))
    .With(multi_argument_matcher)  // Can be used at most once
    .Times(cardinality)            // Can be used at most once
    .InSequence(sequences...)      // Can be used any number of times
    .After(expectations...)        // Can be used any number of times
    .WillOnce(action)              // Can be used any number of times
    .WillRepeatedly(action)        // Can be used at most once
    .RetiresOnSaturation();        // Can be used at most once

      (1).With:将期望限制为仅应用于其参数整体与多参数匹配器multi_argument_matcher匹配的mock函数调用.With子句最多可以在期望中使用一次,并且必须是第一个子句;
      (2).Times:指定期望mock函数调用的次数.参数cardinality(基数)表示期望调用的数量,可以是以下之一,都定义在::testing命名空间中:AnyNumber()、AtLeast(n)、AtMost(n)、Between(m, n)、Exactly(n) or n;
      (3).InSequence:指定mock函数调用应按特定顺序进行.参数sequences...是任意数量的序列对象.
      (4).After:指定mock函数调用顺序发生在一个或多个其它调用之后.
      (5).WillOnce:为单个匹配函数调用指定mock函数在被调用时的实际行为.参数action表示函数调用将执行的操作.
      (6).WillRepeatedly:为所有后续匹配函数调用指定mock函数在调用时的实际行为。在执行WillOnce子句中指定的操作(如果有)后生效。
      (7).RetiresOnSaturation:指示在达到期望的匹配函数调用数后,期望将不再处于活动状态.
      gMock要求在调用mock函数之前设置期望值,否则行为是未定义的。不要在调用EXPECT_CALL和调用mock函数之间交替,并且在将mock传递给API后,不要对mock设置任何期望。这意味着EXPECT_CALL应该被解读为预期将来会发生调用,而不是调用已经发生。
      如果你对参数的值不感兴趣,将_写为参数,这意味着"任何事情都会发生".如果你不关心任何参数,而不是为每个参数指定_,你可以省略参数列表,这适用于所有非重载方法.如果方法重载,则需要通过指定参数的数量以及可能的参数类型来帮助gMock解决预期的重载问题。

      ON_CALL宏语法如下:若要自定义特定mock对象的特定方法的默认操作,使用ON_CALL.它具有与EXPECT_CALL类似的语法,但它用于在不需要调用mock方法时设置默认行为

ON_CALL(mock_object,method_name(matchers...))

      gMock典型的工作流程是
      (1).从testing命名空间导入gMock名称,以便可以不限定地使用它们(每个文件只需执行一次);
      (2).创建一些mock对象;
      (3).指定你对它们的期望(一个方法将被调用多少次?用什么论证?它用过怎么做?等);
      (4).练习(exercise)一些使用mock的code;如有必要,使用GoogleTest断言检查结果;如果一个mock方法被调用的次数超过预期,或者使用了错误的参数,你将立即收到错误;
      (5).当mock被销毁时,gMock将自动检查是否满足了对它的所有期望.

      注:以上内容主要来自于GoogleTest官方文档:gMock for Dummies | GoogleTest

     以下为测试代码:

#include <string>
#include "gmock/gmock.h"

namespace gmock_ {

class Foo {
public:
	// Must be virtual as we'll inherit from Foo.
	virtual ~Foo() {}

	virtual bool SetName(const std::string& name) = 0;
	virtual std::string GetName() const = 0;
};

class MockFoo : public Foo {
public:
	MOCK_METHOD(bool, SetName, (const std::string&), (override));
	MOCK_METHOD(std::string, GetName, (), (const, override));
};

class Area {
public:
	virtual ~Area() {}
	virtual int area() = 0;
};

int GetValue(Area* p) { return p->area() / 2; }

class MockArea : public Area {
public:
	MOCK_METHOD(int, area, (), (override));
};

} // namespace gmock_

TEST(gmock, name) {
	using namespace gmock_;
	using ::testing::AtLeast;
	using ::testing::Return;

	MockFoo foo;
	EXPECT_CALL(foo, SetName("Mike"))
		.Times(AtLeast(2))
		.WillOnce(Return(1))
		.WillOnce(Return(0));
	EXPECT_TRUE(foo.SetName("Mike"));
	EXPECT_FALSE(foo.SetName("Mike"));

	EXPECT_CALL(foo, GetName())
		.Times(AtLeast(1))
		.WillRepeatedly(Return("Mike"));
	EXPECT_EQ("Mike", foo.GetName());
}

TEST(gmock, area) {
	using namespace gmock_;
	using ::testing::Return;

	MockArea m;
	EXPECT_CALL(m, area()).WillRepeatedly(Return(10));
	EXPECT_EQ(5, GetValue(&m));
}

      执行结果如下所示:

      GitHub: https://github.com/fengbingchun/Messy_Test

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/371902.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringCloud学习笔记 - Sentinel流控规则配置的持久化 - Sentinel

1. 为什么要将流控规则持久化 默认的的流控规则是配置在sentinel中的&#xff0c;又因为sentinel是懒加载的&#xff0c;只有当我们访问了一个请求的时候&#xff0c;sentinel才能监控到我们的簇点链路&#xff0c;我们才能对该链路进行流控配置&#xff0c;一旦我们重启应用s…

GNN专栏总览

文章目录图卷积神经网络1. 理论篇2. 模型篇3. 有关gnn的论文检索图卷积神经网络 1. 理论篇 原理&#xff1a;http://xtf615.com/2019/02/24/gcn/论文&#xff1a; 综述类&#xff1a; HOW POWERFUL ARE GRAPH NEURAL NETWORKS?Bridging the Gap between Spatial and Spectra…

PHP实现个人免签约微信支付接口原理+源码

什么是个人免签支付 个人免签支付就是给个人用的支付接口&#xff0c;一般的支付接口都需要营业执照才能申请&#xff0c;个人很难申请的到&#xff0c;或者是没有资质去申请&#xff0c;要和支付商进行签约的。免签&#xff0c;顾名思义就是不需要签约。那么个人免签支付就有…

企业数字化运营平台软件开发框架项目

【版权声明】本资料来源网络&#xff0c;知识分享&#xff0c;仅供个人学习&#xff0c;请勿商用。【侵删致歉】如有侵权请联系小编&#xff0c;将在收到信息后第一时间删除&#xff01;完整资料领取见文末&#xff0c;部分资料内容&#xff1a; 目录 1 项目总体概述 1.1 项目…

Unity Avatar Camera Controller 第一、第三人称相机控制

文章目录简介Variables实现Target PositionTarget RotationOthers简介 本文介绍如何实现用于Avatar角色的相机控制脚本&#xff0c;支持第一人称、第三人称以及两种模式之间的切换&#xff0c;工具已上传至SKFramework框架的Package Manager中&#xff1a; Variables Avatar&…

51单片机入门 - 简短的位运算实现扫描矩阵键盘

介绍 例程使用 SDCC 编译、 stcgal 烧录&#xff0c;如果你想要配置一样的环境&#xff0c;可以参考本专栏的第一篇文章“51单片机开发环境搭建 - VS Code 从编写到烧录”&#xff0c;我的设备是 Windows 10&#xff0c;使用普中51单片机开发板&#xff08;STC89C52RC&#xf…

Qt编写微信支付宝支付

文章目录一 微信支付配置参数二 支付宝支付配置参数三 功能四 Demo效果图五 体验地址一 微信支付配置参数 微信支付API&#xff0c;需要三个基本必填参数。 微信公众号或者小程序等的appid&#xff1b;微信支付商户号mchId&#xff1b;微信支付商户密钥mchKey&#xff1b; 具…

文件基础IO

目录 前言 用库进行文件操作 文件描述符 理解Linux一切皆文件 缓冲区 认识缓冲区 缓冲区缓冲策略 磁盘结构 磁盘分区 软链接和硬链接 硬链接本质 软连接本质 动态库和静态库进阶 写一个静态库 动态库的产生和使用 动静态库的加载 总结&#xff1a; 前言 在我们了…

SE | 哇哦!让人不断感叹真香的数据格式!~

1写在前面 最近在用的包经常涉及到SummarizedExperiment格式的文件&#xff0c;不知道大家有没有遇到过。&#x1f912; 一开始觉得这种格式真麻烦&#xff0c;后面搞懂了之后发现真是香啊&#xff0c;爱不释手&#xff01;~&#x1f61c; 2什么是SummarizedExperiment 这种cla…

lighthouse的介绍和基本使用方法

Lighthouse简介 Lighthouse是一个开源的自动化性能测试工具&#xff0c;我们可以使用该功能检测我们的页面存在那些性能方面的问题&#xff0c;并会生成一个详细的性能报告来帮助我们来优化页面 使用方式 LH一共有四种使用方式 Chrome开发者工具Chrome扩展Node 命令行Node …

数据结构与算法(一)-软件设计(十七)

设计模式&#xff08;十五&#xff09;-面向对象概念https://blog.csdn.net/ke1ying/article/details/129171047 数组 存储地址的计算&#xff1a; 一维数组a[n]&#xff0c;当a[2]的存储地址为&#xff1a;a2*len&#xff0c;如果每一个数组元素只占用一个字节&#xff0c;那…

Spring Batch 高级篇-分区步骤

目录 引言 概念 分区器 分区处理器 案例 转视频版 引言 接着上篇&#xff1a;Spring Batch 高级篇-并行步骤了解Spring Batch并行步骤后&#xff0c;接下来一起学习一下Spring Batch 高级功能-分区步骤 概念 分区&#xff1a;有划分&#xff0c;区分意思&#xff0c;在…

中国ETC行业市场规模及未来发展趋势

中国ETC行业市场规模及未来发展趋势编辑根据市场调研在线网发布的2023-2029年中国ETC行业发展策略分析及战略咨询研究报告分析&#xff1a;随着政府坚持实施绿色出行政策&#xff0c;ETC行业也受到了极大的支持。根据中国智能交通协会统计&#xff0c;2017年中国ETC行业市场规模…

浅析Linux内核进程间通信(信号量)

信号灯与其他进程间通信方式不大相同&#xff0c;它主要提供对进程间共享资源访问控制机制。相当于内存中的标志&#xff0c;进程可以根据它判定是否能够访问某些共享资源&#xff08;临界区&#xff0c;类似于互斥锁&#xff09;&#xff0c;同时&#xff0c;进程也可以修改该…

FreeRTOS任务基础知识

单任务和多任务系统单任务系统单任务系统的编程方式&#xff0c;即裸机的编程方式&#xff0c;这种编程方式的框架一般都是在main&#xff08;&#xff09;函数中使用一个大循环&#xff0c;在循环中顺序的执行相应的函数以处理相应的事务&#xff0c;这个大循环的部分可以视为…

Linux内核共享内存使用常见陷阱与分析

所谓共享内存就是使得多个进程可以访问同一块内存空间&#xff0c;是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制&#xff0c;如 信号量结合使用&#xff0c;来达到进程间的同步及互斥。其他进程能把同一段共享内存段“连接到”他们自己的…

【华为OD机试模拟题】用 C++ 实现 - 最小叶子节点(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 获得完美走位(2023.Q1) 文章目录 最近更新的博客使用说明最小叶子节点题目输入输出示例一输入输出示例二输入输出Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华…

oracle数据库使用JDBC导入ClickHouse数据

一、背景 需求要把oracle中的数据导入到clickhouse中&#xff0c;使用clickhouse的jdbc表引擎&#xff0c;把oracle11g的数据导入到clickhouse中。 二、方案 通过clickhouse-jdbc-bridge&#xff1a;是clickhouse提供的一个jdbc组件&#xff0c;用于通过JDBC的方式远程访问其他…

[面试直通版]网络协议面试核心之IP,TCP,UDP-TCP与UDP协议的区别

点击->计算机网络复习的文章集<-点击 目录 前言 UDP TCP 区别小总结 前言 TCP和UDP都是在传输层&#xff0c;在程序之间传输数据传输层OSI模型&#xff1a;第四层TCP/IP模型&#xff1a;第三层关键协议&#xff1a;TCP协议、UDP协议传输层属于主机间不同进程的通信传…

Unity Lighting -- 光照入门

识别光源 首先来看一张图&#xff0c;看看我们能在这个场景中找到几个光源。 相信大家能够很容易看出来&#xff0c;四盏路灯模型带有四个光源&#xff0c;右边的红绿蓝三个发光的灯也是光源。场景中还有一个光源&#xff0c;这个光源来自天空&#xff0c;让场景看起来有点日落…