Google Mock 只能模拟含纯虚函数的抽象接口,且基类必须有 virtual 析构函数;所有待 mock 函数须为 virtual,至少一个为纯虚;MOCK_METHOD 参数格式须严格匹配,模板接口需同步声明模板参数;未写 EXPECT_CALL 将导致漏测。

Google Mock 只能模拟含纯虚函数的抽象接口,不能直接 mock 具体实现类;如果你的类没有 virtual 析构函数或纯虚函数,MOCK_METHOD 会编译失败。
Mock 类必须继承自抽象接口,且基类析构函数要 virtual
这是最常被跳过的前提。GMock 依赖虚函数表(vtable)做方法拦截,若基类没虚析构,mock 对象销毁时可能未调用期望校验逻辑,甚至引发未定义行为。
-
~Interface()必须声明为virtual = default或virtual ~Interface() = 0 - 所有待 mock 的成员函数必须是
virtual,且至少有一个是纯虚(= 0),否则编译器不认为它是抽象类 - 错误示例:
class DatabaseImpl { public: bool Connect(...); };—— 没有virtual,MOCK_METHOD展开后报error: cannot declare member function 'Connect' to have static linkage
MOCK_METHOD 宏参数顺序和括号嵌套必须严格匹配
宏展开依赖字面量解析,多一个空格、少一个逗号、括号不配对都会导致编译失败,错误信息往往指向“expected ‘,’ before ‘)’”这类语法提示,实际问题在宏参数里。
- 基本格式:
MOCK_METHOD(返回类型, 函数名, (参数列表), (限定符)) - 参数列表外层括号必须存在,哪怕无参也要写
(),不能省略 - 限定符括号内:非 const 方法写
(override),const 方法写(const, override),noexcept等需显式写出 - 带
std::function参数时,类型必须完整,例如:const std::function<void>&</void>,不能简写为std::function
模板接口 Mock 需同步声明模板参数
如果原接口是模板类,Mock 类也必须是模板,并在继承时补全模板实参;否则 MOCK_METHOD 无法绑定到正确函数签名。
立即学习“C++免费学习笔记(深入)”;
- 原接口:
template<typename t> class NetworkClient { virtual void Send(T data) = 0; };</typename> - 正确 Mock:
template<typename t> class MockNetworkClient : public NetworkClient<t> { public: MOCK_METHOD(void, Send, (T data), (override)); };</t></typename> - 错误写法:
class MockNetworkClient : public NetworkClient<int>(非模板类继承模板特化)——会导致Send不被识别为虚函数
EXPECT_CALL 不写就等于没测,NaggyMock 默认只警告
很多测试看似通过,实则没验证任何行为:实例化 MockDatabase mock 后直接调用 mock.Connect("..."),它会静默返回默认值(false、0、空 string 等),而不会报错。
- 必须用
EXPECT_CALL(mock, Connect(_)).Times(1)显式声明你期待这次调用发生 - 若想让未声明调用直接失败,改用
StrictMock<MockDatabase> mock - 忘记写
EXPECT_CALL是 GMock 新手最高频的漏测原因——它不报错,但也不校验
真正难的不是写对 MOCK_METHOD,而是把业务类提前设计成可 mock 的抽象接口;一旦类已固化为具体实现,重构成本远高于写测试本身。


















