C++怎么进行单元测试与Mocking_C++ Google Mock框架(gmock)使用指南

首先配置gmock环境并定义接口,接着创建Mock类模拟依赖行为,然后在测试中通过EXPECT_CALL设定调用期望与返回值,最后验证实际调用是否符合预期。

c++怎么进行单元测试与mocking_c++ google mock框架(gmock)使用指南

在C++项目中进行单元测试时,我们常常需要隔离被测代码的依赖,比如数据库访问、网络请求或复杂的类交互。这时候就需要使用Mocking技术。Google Mock(gmock)是Google Test(gtest)的配套框架,专门用于模拟(Mock)接口行为,验证函数调用,是C++中主流的Mock框架之一。

一、环境准备与基本配置

要使用gmock,首先需要引入Google Test和Google Mock库。你可以通过以下几种方式获取:

使用包管理器安装:如vcpkg、conan或apt(Linux)。从源码编译:从GitHub仓库克隆googletest,其中包含gmock。

示例:使用CMake引入gmock

cmake_minimum_required(VERSION 3.14)project(my_test_project)

引入 Google Test(包含 gmock)

include(FetchContent)FetchContent_Declare(googletestURL https://www.php.cn/link/a8d7ddfb1a52643b880728e1fb453493/archive/refs/tags/v1.14.0.zip)FetchContent_MakeAvailable(googletest)

添加可执行测试文件

enable_testing()add_executable(test_example test.cpp)

链接 gmock_main(自动包含 gtest 和 gmock)

target_link_libraries(test_example gmock_main)

这样就可以在测试代码中直接使用gmock功能。

立即学习“C++免费学习笔记(深入)”;

二、定义接口并创建Mock类

gmock要求你为需要模拟的类定义一个抽象接口(基类),然后继承testing::Mock来创建Mock实现。

示例:定义一个数据服务接口

class DataService {public:    virtual ~DataService() = default;    virtual int fetchData(int id) = 0;    virtual bool saveData(int id, const std::string& data) = 0;};

创建对应的Mock类

#include 

class MockDataService : public DataService {public:MOCK_METHOD(int, fetchData, (int id), (override));MOCK_METHOD(bool, saveData, (int id, const std::string& data), (override));};

MOCK_METHOD宏用于声明模拟方法。语法为:

MOCK_METHOD(return_type, method_name, (arg_list), (qualifiers...));

其中(override)表示该方法重写了基类虚函数,C++11以后推荐加上。

三、在测试中使用Mock对象

接下来,在测试中注入Mock对象,设定预期行为,并验证调用情况。

示例:测试一个依赖DataService的业务类

class DataProcessor {public:    explicit DataProcessor(DataService* service) : service_(service) {}
std::string process(int id) {    int value = service_->fetchData(id);    if (value > 100) {        service_->saveData(id, "large");        return "large";    } else {        service_->saveData(id, "small");        return "small";    }}

private:DataService* service_;};

编写测试用例

#include #include 

using ::testing::Return;using ::testing::Exactly;using ::testing::_;using ::testing::Test;

TEST(DataProcessorTest, ReturnsLargeWhenValueGreaterThan100) {MockDataService mockService;DataProcessor processor(&mockService);

// 设定期望:fetchData(42) 返回 150EXPECT_CALL(mockService, fetchData(42))    .WillOnce(Return(150));// 验证 saveData 被调用一次,且第二个参数为 "large"EXPECT_CALL(mockService, saveData(42, "large"))    .Times(1);std::string result = processor.process(42);EXPECT_EQ(result, "large");

}

关键点说明:

EXPECT_CALL 设置对Mock方法的调用期望。WillOnce(Return(value)) 指定返回值。_ 可作为通配符匹配任意参数。测试结束时,gmock会自动验证所有期望是否满足。

四、常用Matcher与行为控制

gmock提供了丰富的匹配器(Matcher)和行为(Action)来灵活控制Mock逻辑。

常见Matcher示例

EXPECT_CALL(mockService, fetchData(_));                    // 任意参数EXPECT_CALL(mockService, fetchData(42));                   // 参数等于42EXPECT_CALL(mockService, fetchData(Gt(100)));              // 大于100EXPECT_CALL(mockService, saveData(42, StartsWith("s")));   // 字符串前缀匹配

多种返回行为

.WillOnce(Return(42));.WillOnce(Return(true)).WillOnce(Return(false));  // 第一次true,第二次false.WillRepeatedly(Return(0));                       // 后续调用都返回0.WillOnce(DoAll(PrintArg(), Return(100)));    // 执行多个动作

你也可以自定义Action或验证调用顺序:

Sequence s;EXPECT_CALL(mockService, fetchData(42)).InSequence(s);EXPECT_CALL(mockService, saveData(_, _)).InSequence(s);

这表示两个调用必须按顺序发生。

基本上就这些。掌握gmock的核心在于理解Mock类的定义方式、EXPECT_CALL的使用以及如何设置返回值和验证调用。结合gtest,你可以构建出稳定可靠的C++单元测试体系。实际项目中建议将Mock对象通过依赖注入传入,便于解耦和测试。整个过程不复杂但容易忽略细节,比如忘记加virtualoverride会导致Mock失效,需多加注意。

以上就是C++怎么进行单元测试与Mocking_C++ Google Mock框架(gmock)使用指南的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1486060.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
C++怎么实现一个外观设计模式_C++结构型模式与子系统接口封装
上一篇 2025年12月19日 09:28:37
C++如何处理异常_C++中使用try-catch-throw进行错误处理
下一篇 2025年12月19日 09:28:53

相关推荐

  • AI做音乐推荐怎么实现_Spotify推荐算法原理与应用

    AI做音乐推荐怎么实现_Spotify推荐算法原理与应用AI做音乐推荐怎么实现_Spotify推荐算法原理与应用AI做音乐推荐怎么实现_Spotify推荐算法原理与应用AI做音乐推荐怎么实现_Spotify推荐算法原理与应用

    答案:AI音乐推荐通过协同过滤、内容分析、混合系统和上下文感知等多维度算法,结合用户行为与歌曲特征,实现个性化推荐。Spotify利用隐式反馈、音频特征提取、深度学习和NLP技术,融合用户偏好与情境因素,解决冷启动问题,并在探索与利用间平衡,持续优化用户体验。 ☞☞☞AI 智能聊天, 问答助手, A…

    2026年9月4日 用户投稿
    000
  • 高效处理地理数据:webeweb/geo-json-library 的实践指南

    在开发一个基于位置服务的应用时,我需要处理大量的地理位置数据,这些数据以geojson格式存储。geojson是一种用于表示地理数据的开放标准,它包含多种地理对象类型,例如点、线、多边形等,结构相对复杂。一开始,我尝试使用php自带的json_decode函数解析geojson数据,然后手动处理其中…

    用户投稿 2026年9月4日
    000
  • 美图秀秀在线版官方入口 美图秀秀手机在线修图

    美图秀秀在线版官方入口为https://pc.meitu.com,进入后可使用海报设计、智能抠图、拼图、证件照制作等功能,支持响应式操作与云端同步,具备AI画质修复、去水印、视频优化及超大图片处理技术。 美图秀秀在线版官方入口在哪里?这是不少网友都关注的,接下来由PHP小编为大家带来美图秀秀在线修图…

    2026年9月4日
    100
  • 告别缓慢的GraphQL查询:使用Graphpinator Persisted Queries提升性能

    最近,我负责维护一个使用graphql的api,随着用户数量的增加,api的响应速度逐渐变慢。分析后发现,许多用户都在重复发送相同的查询,导致服务器在解析和验证这些查询上浪费了大量资源。虽然我的解析器函数本身效率很高,但graphql本身的解析和验证过程却成为了瓶颈。为了解决这个问题,我尝试了多种方…

    用户投稿 2026年9月4日
    000
  • Linux文件系统目录结构详解

    大家好,又见面了,我是你们的朋友全栈君。 引言 对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解#%#$#%@%@%$#%$#%#%#$%@_e206a54e97690c++e50cc872dd70ee896文件目录结构的标准和每个目录的…

    2026年9月4日
    200
  • 世界级人工智能科学家许主洪加盟阿里巴巴,担任副总裁

    世界级人工智能科学家许主洪加盟阿里巴巴,担任副总裁世界级人工智能科学家许主洪加盟阿里巴巴,担任副总裁世界级人工智能科学家许主洪加盟阿里巴巴,担任副总裁世界级人工智能科学家许主洪加盟阿里巴巴,担任副总裁

    凤凰网科技讯 2月6日,凤凰网科技获悉,全球顶尖人工智能科学家许主洪教授(steven hoi)正式加入阿里巴巴,出任阿里集团副总裁,负责ai to c业务的多模态基础模型及agents相关基础研究与应用解决方案。近期,阿里ai to c业务大动作频频,引入世界级顶尖人才,组建顶级ai算法研究和工程…

    2026年9月4日 用户投稿
    100
  • 告别猴子补丁:使用bafs/illuminate-demacroable提升代码稳定性

    最近在维护一个大型laravel项目时,我发现项目中大量使用了宏(macros),这些宏通过illuminate/macroable提供的猴子补丁机制动态地扩展了核心组件的功能。虽然这在开发过程中带来了便利,但同时也带来了潜在的风险: 代码难以理解和维护: 动态添加的功能难以追踪,增加了代码理解和维…

    用户投稿 2026年9月4日
    100
  • linux进入单用户模式的方法介绍

    redhat7.2 在使用grub引导程序的时候如何进入单用户 1.在出现GURB引导画面时,按字母e,进入GRUB编辑状态 2在引导菜单后添加“1”或single,选定它,然后按字母b,就可引导到单用户模式了。  例如: red hat linux 7.2,未编辑时引导菜单是:  RedHat L…

    用户投稿 2026年9月4日
    100
  • linux下如何删除乱码文件的方法

    在linux下删除文件,遇到特殊字符是一件非常头疼的事情。 1. 如果文件名带 ‘-’ 或者‘–’这样的字符 删除办法为:rm — 文件名  如文件名为:-pythontab.tgz 如果用普通方法去删除: rm -pythontab.tgz 结果错误: rm: invali…

    用户投稿 2026年9月4日
    100
  • 华人研究团队揭秘:DeepSeek-R1-Zero或许并不存在「顿悟时刻」

    华人研究团队揭秘:DeepSeek-R1-Zero或许并不存在「顿悟时刻」华人研究团队揭秘:DeepSeek-R1-Zero或许并不存在「顿悟时刻」华人研究团队揭秘:DeepSeek-R1-Zero或许并不存在「顿悟时刻」华人研究团队揭秘:DeepSeek-R1-Zero或许并不存在「顿悟时刻」

    deepseek 模型的“顿悟时刻”再研究:自我反思并非训练的关键 近期围绕DeepSeek模型的“顿悟时刻”(模型展现出自我反思等涌现能力)引发广泛关注。然而,新加坡Sea AI Lab等机构的研究者对这一现象进行了深入探究,并得出了一些与先前认知不同的结论。 过去的研究认为,DeepSeek-R…

    2026年9月4日 用户投稿
    100
  • 灵活的路由配置:RollerworksRouteAutowiringBundle 的实践指南

    在开发一个大型 symfony 应用时,我们通常会将应用拆分成多个模块(bundle)。每个模块都拥有自己的路由配置,传统的做法是将这些路由配置分别定义在各个模块中,然后在主应用的路由配置文件中逐一导入。这种方法存在一些问题: 维护成本高: 随着模块数量的增加,主应用的路由配置文件会变得越来越臃肿,…

    用户投稿 2026年9月4日
    600
  • Windows系统启用并安装linux子系统(WSL)教程

    Windows系统启用并安装linux子系统(WSL)教程Windows系统启用并安装linux子系统(WSL)教程Windows系统启用并安装linux子系统(WSL)教程Windows系统启用并安装linux子系统(WSL)教程

    第一步,启动windows设置面板 第二步,进入应用与功能设置 在应用与功能设置中,点击程序与功能选项 立即进入“豆包AI人工智官网入口”; 立即学习“豆包AI人工智能在线问答入口”; 第三步,启用或关闭Windows功能 第四步,选择并激活所需功能 第五步,在Microsoft商店中搜索WSL 第…

    2026年9月4日 用户投稿
    200
  • Java Tab选项多参数处理:如何优雅地使用枚举处理前端传来的多个键值对参数?

    Java Tab选项多参数处理:利用枚举优雅处理前端键值对参数 Java后端常常需要处理前端Tab选项传递的多个键值对参数。例如,前端可能发送”week”、”month”或”quarter”参数,要求服务器返回对应的数据。本文介…

    2026年9月4日
    100
  • MAC的隔空投送(AirDrop)搜不到设备怎么办_MAC AirDrop搜不到设备解决方法

    首先检查设备Wi-Fi和蓝牙是否开启,并确保隔空投送设置为“所有人”或“仅限联系人”;接着重启所有设备以排除临时故障;若问题仍存在,尝试退出并重新登录iCloud账户以重置网络与同步状态;为进一步排查,可启动Mac安全模式以排除第三方软件干扰;最后通过创建新管理员账户判断是否为用户配置文件损坏所致。…

    2026年9月4日
    200
  • linux中关于socket通讯获取本地的源端口号的实现方法

    这篇文章主要介绍了linux socket通讯获取本地的源端口号的相关资料,需要的朋友可以参考下 关于TCP IP网络通讯的资料非常多,TCP IP通过IP数据包模式进行端对端通讯。典型的TCP数据包如下 可以看到数据包包含了源端口号和目的端口号,客户端socket向服务端发起连接时,系统会给soc…

    2026年9月4日
    200
  • 东风猛士917接入DeepSeek-R1模型 4月前通过OTA推送 

    东风猛士917智能座舱即将搭载deepseek-r1模型,引领汽车行业ai智能化新潮流!据悉,猛士科技将于2025年4月北京车展前,通过ota升级,率先在猛士917和蛟龙战甲等车型上推出这项技术。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜…

    2026年9月4日
    200
  • 如何在Java中实现对象缓存机制

    答案:Java对象缓存通过减少重复创建和远程调用提升性能,常用HashMap或ConcurrentHashMap实现简单缓存,结合TTL和LRU策略控制内存,推荐使用Guava Cache或Caffeine进行高级管理,并在分布式环境下采用Redis集成,配合Spring Cache注解简化开发,核…

    2026年9月4日
    100
  • linux中关于gzip命令的实例分析

    gzip是在linux系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用。接下来通过本文给大家分享linux 中的gzip命令,感兴趣的朋友一起看看吧 gzip命令用来压缩文件。gzip是个使用广泛的压缩程序,文件经它压缩过后,其名称后面会多处“.gz”扩展名。 gzip是在Linux系…

    用户投稿 2026年9月4日
    100
  • linux中关于ls命令的实例详解

    ls命令是linux下最常用的命令。ls命令就是list的缩写。下面通过本文给大家分享linux 中ls命令详解,感兴趣的朋友一起看看吧 ls命令用来显示目标列表,在Linux中是使用率较高的命令。ls命令的输出信息可以进行彩色加亮显示,以分区不同类型的文件。 语法 ls(选项)(参数) 选项 -a…

    用户投稿 2026年9月4日
    100
  • linux中关于mkdir命令的详解

    mkdir 是一个用来在 linux 系统下创建目录的命令。此命令属于内建命令。接下来通过本文给大家分享linux mkdir命令详解,感兴趣的朋友一起看看吧 mkdir命令用来创建目录。该命令创建由dirname命名的目录。如果在目录名的前面没有加任何路径名,则在当前目录下创建由dirname指定…

    用户投稿 2026年9月4日
    200

发表回复

登录后才能评论
关注微信