c++ 单元测试mock方法 c++如何使用gmock进行mock测试

大枫酱_8892

大枫酱_8892

2026-03-21

528人浏览

原创

gmock的mock_method必须在类定义内声明虚函数,expect_call需在调用前设置,且须正确链接-lgmock -lgtest;三者缺一不可。

c++ 单元测试mock方法 c++如何使用gmock进行mock测试

gmock 的 MOCK_METHOD 必须写在类定义里,不能在类外或模板特化里直接写

你写了个类想 mock 它的虚函数,但编译报错说 MOCK_METHOD 不是有效声明?大概率是因为把它放在了类定义之外,或者试图在非虚函数上用、或在未继承的类上用。gmock 要求被 mock 的函数必须是 public virtual,且 MOCK_METHOD 宏必须作为类成员声明的一部分出现在类体中。

  • MOCK_METHOD 本质是生成一个带特定签名的虚函数重写 + 内部调用记录逻辑,所以它依赖类的继承结构和虚表布局
  • 如果原接口函数不是 virtual,gmock 无法接管调用,mock 就完全不生效 —— 运行时仍走原实现
  • 模板类的 mock 需显式特化后才能用 MOCK_METHOD;直接对模板类本身写会触发编译错误,比如 MOCK_METHOD(int, foo, ())template<typename t> class A</typename> 里非法
  • 常见错误现象:error: 'MOCK_METHOD' does not name a type,往往是因为宏没展开(忘了 #include <gmock></gmock>)或位置不对

测试中调用 EXPECT_CALL 必须在被测代码执行前设置,且作用域要匹配

你写了 EXPECT_CALL(obj, func()),但测试还是崩溃或提示“unexpected call”,说明 mock 行为没被正确绑定。gmock 的期望是运行时检查机制,不是编译期约束,它的生命周期和作用域必须覆盖实际调用点。

C++
C++

"空空如也"

下载
  • EXPECT_CALL 调用后立即生效,但只对后续发生的调用起作用;如果被测函数在 EXPECT_CALL 前就执行了,mock 完全不介入
  • 如果 mock 对象是局部变量,EXPECT_CALL 写在它构造之后、被测逻辑之前即可;但若对象由工厂返回或注入到其他对象中,要确保 EXPECT_CALL 设置发生在该对象真正被使用前
  • 多个 EXPECT_CALL 对同一函数的设置会叠加,但顺序敏感:后设的会覆盖前设的「次数限制」,比如先写 EXPECT_CALL(a, f()).Times(1),再写 EXPECT_CALL(a, f()).Times(2),最终以 2 次为准
  • 别在测试函数返回后还指望 EXPECT_CALL 生效 —— mock 对象析构时会自动验证未满足的期望,失败则直接让测试断言失败

gmock 默认严格模式,未声明的调用直接导致测试失败

你没写 EXPECT_CALL,但被测代码调用了 mock 对象的某个函数,测试却挂了,报错类似 Uninteresting mock function call —— 这是 gmock 的默认行为:任何未预期的虚函数调用都会触发失败。这不是 bug,是设计使然。

  • 如果你确实需要允许某些调用不声明(比如日志函数、getter),得显式用 ON_CALL + WillByDefault 设默认行为,例如:ON_CALL(mock_obj, log(_)).WillByDefault(Return());
  • 想临时关闭严格模式,可用 testing::StrictMock 替换为 testing::NiceMock:后者对未声明调用只警告不失败;但生产级测试建议坚持 Strict,避免漏掉关键交互
  • 注意 ON_CALL 只设默认响应,不验证调用次数;真正要校验是否被调用、调多少次,还得靠 EXPECT_CALL
  • 常见陷阱:把 ON_CALL 写在 EXPECT_CALL 后面,结果后者被前者覆盖 —— 实际上 ON_CALLEXPECT_CALL 是正交的,但同名函数上后者优先级更高

链接 gmock 时容易忽略 -lgmock -lgtest 顺序和 ABI 兼容性

编译通过但链接时报 undefined reference 到 testing::internal::GetTestTypeId() 或一堆 Mock::VerifyAndClearExpectations,基本是链接顺序或 ABI 不一致导致的。

  • 链接选项顺序很重要:-lgmock 必须在 -lgtest 之前,因为 gmock 依赖 gtest 的基础设施;反过来会找不到符号
  • 如果你用系统包管理器装的 gtest/gmock(如 Ubuntu 的 libgtest-dev),默认可能是静态库且无调试信息,和你自己用 CMake 构建的动态版混用会出 ABI 冲突 —— 强烈建议统一用 CMake 的 find_package(GTest REQUIRED) 并启用 GTEST_FORCE_SHARED_CRT
  • 在 macOS 上还要额外加 -framework Foundation(尤其用到时间相关 mock 时),否则可能链接失败或运行时 crash
  • 常见错误信息:undefined reference to 'testing::Mock::AllowLeak(testing::Mock const&)',大概率就是库版本不匹配或链接顺序颠倒
gmock 的核心约束其实就三点:虚函数是前提、期望要提前设、链接得对得上。最难调的往往不是语法,而是 mock 对象的生命周期和被测代码的实际调用路径没对齐 —— 多打两行 LOG(INFO) 比反复改 <code>EXPECT_CALL 更快定位问题。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.18

869

5

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.25

2300

5

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2023.09.20

1898

7

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

5059

3

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.08.29

2605

6

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.29

3148

10

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2025.08.29

2205

10

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

2023.10.19

3028

3

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

2025.10.17

4189

12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Valgrind Quick Start Guide
Valgrind Quick Start Guide

共0课时 | 0人学习

CLion CMake 快速入门教程
CLion CMake 快速入门教程

共0课时 | 0人学习