因为接口类缺少虚析构函数且被模拟方法非virtual,导致析构未定义行为及mock拦截失效;MOCK_METHOD需严格匹配原函数签名,含const、noexcept等限定符,否则编译失败。

为什么直接继承接口类写 Mock 类会编译失败
因为 Google Mock 要求所有被 MOCK_METHOD 模拟的函数必须是 virtual,且接口类通常缺少虚析构函数——一旦用 std::unique_ptr<Interface> 或基类指针接收 Mock 对象,析构时就会未定义行为(UB),常见表现是程序崩溃或内存泄漏。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 接口类必须声明
virtual ~Interface() = default;(哪怕空实现) - 如果原接口来自第三方头文件且无法修改,用
class Wrapper : public ExternalInterface封装一层,并在Wrapper中补上虚析构 - 避免在 Mock 类中重写非 virtual 函数;GMock 不会拦截它们,调用仍走原实现
MOCK_METHOD 宏参数顺序和 const 限定符怎么配才不报错
错误常发生在返回类型、参数列表、const 与 noexcept 标记不完全匹配原函数签名。GMock 对类型精度极其敏感:比如原函数是 const std::string&,写成 std::string 就会导致编译器找不到匹配的 MOCK_METHOD 声明。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用 IDE(如 CLion/VS2022)右键跳转到原函数声明,复制完整签名,再粘贴进
MOCK_METHOD -
MOCK_METHOD第三个参数是调用限定符,必须显式写出:MOCK_METHOD(int, GetId, (), (const, noexcept))—— 缺少(const)会导致 const 成员函数调用失败 - 含右值引用或模板参数的函数无法直接 mock,需改用
MOCK_METHOD的变体宏(如MOCK_METHOD_R已废弃,统一用标准宏 + 显式类型)
如何让 GMock 验证带指针/引用参数的外部调用是否传入了预期值
默认 EXPECT_CALL 只比对参数地址或原始值,对指针解引用内容、对象字段、容器元素等不自动深比较。例如传入 const Config*&,只校验指针是否为同一地址,而非其指向内容是否符合预期。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用
Pointee()匹配器验证指针所指对象:EXPECT_CALL(mock, LoadConfig(Pointee(Field(&Config::timeout, Eq(5000))))); - 对
std::shared_ptr<T>用Pointee()或Truly([](const auto& p) { return p->id == 42; }) - 避免直接写
Eq(some_ptr),它比的是指针值;要内容一致,必须解引用或用自定义匹配器
GTest + GMock 在 CI 环境里链接失败或符号未定义怎么办
典型错误是 undefined reference to testing::internal::GetArgPrinter 或 Mock::AllowLeak,本质是 GMock 库没正确链接,或头文件与库版本不一致(比如头文件是 v1.12,但链接的是 v1.10 的 libgmock.a)。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- CMake 中必须同时
find_package(gtest REQUIRED)和find_package(gmock REQUIRED),并链接gmock_main(含 main)或gmock(不含 main) - 不要手动
#include <gmock/gmock.h>后又链接系统 apt/yum 安装的老版本;统一用 vcpkg/conan/fetchcontent 管理 GMock 源码构建 - 启用
-DGTEST_LINKED_AS_SHARED=ON时,确保测试可执行文件也动态链接 libgmock.so,而非静态混用
SetArgPointee、Invoke 或工厂类注入,而不是硬刚 mock 深层依赖。


















