GoogleTest之创建Mock

news2024/11/23 18:37:33

目录

  • MOCK_METHOD
  • mock方法的访问属性
  • mock非虚函数
  • mock自由函数
  • Nice/Strict/Naggy
  • mock方法简化参数
  • mock具体类的替代方法
  • 代理给fake

mock是用来模拟对象,隔离边界的一种测试方法,以便在开发阶段不需要依赖第三方或其他依赖项可以进行独立的测试。

MOCK_METHOD

使用MOCK_METHOD 宏生成mock方法。MOCK_METHOD 宏有三到四个参数,前三个参数为函数签名分成的三部分(返回值,函数名,参数),第四个参数为以下一个或多个,逗号分隔:

  • const:使这个mock方法成为一个const函数,如果重写的函数时const函数,则这个是必须的。
  • override:同C++中的override,如果是重写虚函数,建议加上该关键字
  • noexpect:如果重写的函数时noexpect,那mock方法也是要加上的
  • Calltype(…):只在windows上有效
  • ref(…):TODO

MOCK_METHOD 形如:MOCK_METHOD(int, my_func, (int x, string y), (const, override));

mock方法的访问属性

不管base class中函数的属性是哪种,mock方法必须都是public。因为这样ON_CALL和EXPECT_CALL可以在mock类外访问。

mock非虚函数

mock非虚函数的mock类除了使用MOCK_METHOD 定义的mock函数签名一样外,其他和原类没有任何关系了。

class ConcretePacketStream {
 public:
  void AppendPacket(Packet* new_packet);
  const Packet* GetPacket(size_t packet_number) const;
  size_t NumberOfPackets() const;
};

class MockPacketStream {
 public:
  MOCK_METHOD(const Packet*, GetPacket, (size_t packet_number), (const));
  MOCK_METHOD(size_t, NumberOfPackets, (), (const));
};

实际上相当于重新写了不相关的mock类,只是保持了类函数签名一样。在mock类中可以按实际需要mock函数,不需要mock原类中的所有函数。

  • mock非虚函数需要在编译期就要决定是哪个对象,这一点不像虚函数。解决这个问题的一种方法是模板化你的代码。在生产代码中使用原类,在测试代码中使用mock类作为模板参数传入(策略模式)(这种使用场景需要再了解TODO)

mock自由函数

无法mock一个自由函数(不是类的成员函数都叫自由函数),但是可以通过以下方式实现:

  1. 实现一个接口类,在继承这个接口类的函数中调用这个自由函数以实现mock它的功能。
class FileInterface {
 public:
  ...
  virtual bool Open(const char* path, const char* mode) = 0;
};

class File : public FileInterface {
 public:
  ...
  bool Open(const char* path, const char* mode) override {
     return OpenFile(path, mode);
  }
};
  1. 通过mock std::function实现。
  • ::testing::MockFunction<R(T1, ..., Tn)>有两个mock方法:
    • R Call(T1, ..., Tn)
    • std::function<R(T1, ..., Tn)> AsStdFunction()
  • 实现步骤:
    • 创建一个MockFunction对象,签名和要mock的free function保持一致
    • 在期望EXPECT_CALL中使用Call
    • 使用AsStdFunction()实现调用mock函数的调用。
  • 用途:
    • 可以mock自由函数
    • 可以mock回调函数,作为参数传递

示例

TEST(FooTest, RunsCallbackWithBarArgument) {
  MockFunction<int(string)> mock_function;  // 声明MockFunction对象,自由函数的签名为int xx(string);
  EXPECT_CALL(mock_function, Call("bar")).WillOnce(Return(1)); // 这里指定期望的调用
  std::function<int(string)> f = mock_function.AsStdFunction(); // 取出mock函数并调用
  EXPECT_EQ(f("bar"), 11);
}

Nice/Strict/Naggy

TEST(...) {
  MockFoo mock_foo;
  EXPECT_CALL(mock_foo, DoThis());
  ... code that uses mock_foo ...
}

如果mock函数没有EXPECT_CALL但是被调用了。这种被称为不感兴趣的调用,会有告警信息。如下:
在这里插入图片描述
如果要忽略这种信息,可以使用NiceMock<MockFoo>代替mock_foo
NiceMock<MockFoo>是MockFoo的一个子类。以下方式调用完之后没有uninsterestring信息。

using ::testing::NiceMock;
TEST(test_override, mock_override02) {
    NiceMock<MockFoo> foo;   // 使用NiceMock<MockFoo>代替MockFoo
    EXPECT_CALL(foo, Add(::testing::_))
    .Times(1)
    .WillRepeatedly(testing::Return(12));

    EXPECT_EQ(foo.DoThis(), 12);
}

StrictMock 的用法和NiceMock一样,期望所有的不感兴趣的调用失败。(看输出结果和NiceMock基本一样,不知道有啥区别?)
注意事项:

  • NiceMock<MockFoo> and StrictMock<MockFoo>只作用于使用MOCK_METHOD 宏定义的mock函数中,如果mock函数定义在MockFoo的base类中,NiceMock或StrictMock不会影响它。
  • 如果MockFoo 类的析构是非虚函数,NiceMock<MockFoo>StrictMock<MockFoo>可能不会正常工作

mock方法简化参数

有时候要mock的方法有很多入参,这些入参大部分不需要,可以通过以下示例中的方式进行在mock函数中进行简化

class LogSink {
public:
    virtual void send(int severity, const char* full_filename,
                    const char* base_filename, int line,
                    const int* tm_time,
                    const char* message, size_t message_len) = 0;
};

class ScopedMockLog : public LogSink {
public:
    void send(int severity, const char* full_filename,
                    const char* base_filename, int line, const int* tm_time,
                    const char* message, size_t message_len) override {
    Log(severity, full_filename, base_filename);
    std::cout << "ScopedMockLog::send" << std::endl;
  }

  MOCK_METHOD(void, Log, (int severity, const string& file_path, const string& message));
};

TEST(test_simplify, mock_simplify) {
    mock_simplify::ScopedMockLog log;
    EXPECT_CALL(log, Log(1, "a.txt", "bbb")).WillOnce([](int x, const string& file_path, const string& message){
        std::cout << "x: " << x << ", file_path is: " << file_path << ", message: " << message << std::endl;
    });

    log.Log(1, "a.txt", "bbb");
}

分析:接口类LogSink 的send方法中我们只用到severity,file_path和message这三个参数,其他不需要,可以通过在派生的mock类中实现这个虚函数而不是直接mock它。并定义一个只需要这三个参数的新函数(通过MOCK_METHOD定义)在后续测试程序中使用就OK了。

mock具体类的替代方法

通过给具体类定义一个父接口类的方式

代理给fake

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

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

相关文章

MySQL调优系列(六)——查询优化

一、查询慢的原因 查询速率受网络、CPU、IO、上下文切换、系统调用、生成统计信息、锁等待时间等因素影响。 举个常见面试题&#xff1a; 一个表非常非常大&#xff0c;上亿级别的数据&#xff0c;性能会变慢嘛&#xff1f;如果表有索引 答&#xff1a;增删改会变慢。&#xf…

Python可视化分析项目高分课设

今天给大家分享一个基于python的django框架结合爬虫以及数据可视化和数据库的项目&#xff0c;该项目总体来说还是挺不错的&#xff0c;下面针对这个项目做具体介绍。 1&#xff1a;项目涉及技术&#xff1a; 项目后端语言&#xff1a;python 项目页面布局展现&#xff1a;前…

数据结构--队列

文章目录 队列基础队列的实现链表实现环形数组实现tail一直加的问题容量处理 队列的使用 队列基础 queue 是以顺序的方式维护的一组数据集合 相对于链表来说&#xff0c;队列操作数据的位置是固定的只能2端操作。 在一端添加数据&#xff0c;从另一端移除数据。习惯来说&#…

高完整性系统(3):Threat Modelling

文章目录 基础安全性质保密性&#xff08;Confidentiality&#xff09;完整性&#xff08;Integrity&#xff09;可用性&#xff08;Availability&#xff09;认证&#xff08;Authentication&#xff09;不可抵赖性&#xff08;Non-repudiation&#xff09;访问控制&#xff0…

从开源软件看动态内存分配

动态内存分配 我们通常在C里面动态分配内存&#xff0c;会写出下面这样的代码&#xff1a; struct header {size_t len;unsigned char *data; }; 随后为data malloc一段内存出来&#xff0c;那么还有其他办法吗&#xff1f; 那便是弹性数组&#xff01;在阐述本节之前&#xff…

数据安全有隐患?金仓数据60秒邀你闯关破题赢奖品

数字时代 数据成为宝贵资产 数据的安全 更是关乎行业可持续发展 关乎社会的稳定和国家战略 数据库作为 数据安全的首要防线 如何纵深防御 保障数据安全合规 满足新应用新场景下的安全防护要求 金仓数据60秒 发布多个视频为您详细剖析 同时&#xff0c;小编发起“闯关挑战”活动…

【Linux】14. 文件缓冲区

1. 文件缓冲区的引出 如上现象&#xff0c;在学习完文件缓冲区之后即可解释 2. 认识缓冲区 缓冲区的本质就是内存当中的一部分&#xff0c;那么是谁向内存申请的&#xff1f; 是属于谁的&#xff1f; 为什么要存在缓冲区呢&#xff1f; 道理是如此&#xff0c;在之前的学习过…

基于matlab仿真带有飞机的虚拟场景

一、前言 此示例演示如何通过 MATLAB接口使用空间鼠标。 开始此示例后&#xff0c;带有飞机的虚拟场景将显示在 Simulink 3D 动画查看器中。您可以使用空格鼠标在场景中导航平面。通过按下设备按钮 1&#xff0c;您可以在当前平面位置放置标记。 此示例需要空间鼠标或其他兼容设…

Neuralangelo AI - 视频生成3D模型

NVIDIA Research 宣布了 Neuralangelo&#xff0c;这是一种创新的 AI 模型&#xff0c;它利用神经网络的力量从 2D 视频剪辑中重建详细的 3D 结构。 Neuralangelo 能够生成逼真的建筑物、雕塑和其他现实世界物体的虚拟复制品&#xff0c;展示了 AI 在 3D 重建领域的非凡潜力。…

十个国内可用的智能AI模型

AI语言模型&#xff0c;就是一种利用机器学习和自然语言处理技术进行文本生成的算法。其基于大量已有的语料库进行训练&#xff0c;建立出一个能够理解自然语言规律和特征的语言模型。对于输入的文本、任务和目标&#xff0c;AI语言模型可以快速生成对应的结果。 在实际应用中&…

Flume入门监控端口数据官方案例

Flume安装部署 相关地址 Flume官网地址&#xff1a;http://flume.apache.org/文档查看地址&#xff1a;http://flume.apache.org/FlumeUserGuide.html下载地址&#xff1a;http://archive.apache.org/dist/flume/ 安装 将apache-flume-1.9.0-bin.tar.gz上传到linux的/opt/s…

责任链模式的学习与使用

1、责任链模式的学习 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许你将请求沿着处理链进行传递&#xff0c;直到有一个处理者能够处理该请求。责任链模式将请求的发送者和接收者解耦&#xff0c;使多个对象都有机…

计算机网络通信过程

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

案例|某城商行Zabbix 监控架构分享

编者荐语&#xff1a; 东莞银行董天保将出席7月份Zabbix大会分享案例经验&#xff0c;欢迎参加&#xff01; 以下文章来源于有田菜也香 &#xff0c;作者AcidGo 东莞银行董天保先生将于7月份参加Zabbix大会分享使用经验&#xff0c;欢迎扫码参加&#xff01; 【导读】某银行…

openCV(三)绘制几何图形

openCV内置了几何图形绘制函数&#xff0c;通过简单的操作就可以绘制几何图形。例如&#xff0c;可以绘制直线、矩形、圆形、椭圆、多边形、文字等&#xff0c;分别对应函数cv2.line()、cv2.rectangle()、cv2.circle()、cv2.ellipse()、cv2.polylines()、cv2.putText()。 下面来…

Mysql进阶【3】论述Mysql优化

1.通过explain查看sql的详细信息 Mysql的sql优化企业里边主要是对慢sql进行优化&#xff0c;对语句进行优化&#xff0c;对索引进行优化 通过explain查看sql的详细信息&#xff0c;并且分析sql语句存在的问题&#xff0c;比如有没有使用到索引、使用了索引还是慢是不是索引设…

第一章_从减库存聊起

在多线程高并发场景下&#xff0c;为了保证资源的线程安全问题&#xff0c; jdk 为我们提供了 synchronized 关键字和 ReentrantLock 可重入锁&#xff0c;但是它们只能保证一个 jvm 内的线程安全。在分布式集群、微服务、云原生横行的当下&#xff0c;如何保证不同进程、不同…

2023年京东618预售数据:传统滋补成预售黑马,预售额超27亿

这一期主要分享一下此次京东618预售期间的一个黑马行业——传统滋补。不管是从预售量和预售额来看&#xff0c;传统滋补品类的成绩都是此次大促中的佼佼者。 究其原因&#xff0c;近几年养生滋补也掀起了一股“国潮风”。在小红书、抖音等社交平台上&#xff0c;关于“健康养生…

车载摄像头专用——拓尔微低功耗超高集成PMIC TMI7205B

“2023将是汽车行业的大变革之年&#xff0c;全球迎来L2向L3/L4跨越窗口。”越高级别的自驾对周围环境感知要求越高&#xff0c;车载摄像头“高清化”势不可挡&#xff0c;目前已从传统的100万直接跃升至800万像素摄像头&#xff0c;甚至在供应层面&#xff0c;已有超1500万高像…

Vue.js 中的 $forceUpdate 方法是什么?有什么作用?

Vue.js 中的 $forceUpdate 方法是什么&#xff1f;有什么作用&#xff1f; 在 Vue.js 中&#xff0c;$forceUpdate 方法是一个很常见的方法之一。它可以强制组件重新渲染&#xff0c;从而让组件的视图更新。本文将介绍 $forceUpdate 方法的使用方法和作用&#xff0c;并给出一…