Google Mock中如何按需选择是否mock指定成员函数
Google Mock 按需mock函数实现方案
不需要额外创建移除MOCK_METHOD的重复mock类,Google Mock原生支持按需选择走mock逻辑还是基类真实实现,以下是可直接落地的方案:
首先先修正你代码中的笔误:你写的MOCK_MOTHOD0存在拼写错误,旧版GMock对应正确宏为MOCK_METHOD0,新版GMock推荐使用通用写法MOCK_METHOD(bool, functionB, ()),拼写错误会直接导致编译失败。
方案1:单测中按需设置调用真实实现
这是最灵活的实现方式,仅需在原有mock类中补充一个访问基类protected方法的辅助接口解决访问权限问题即可,不需要改动原有mock逻辑:
- 先在mock类中补充调用基类真实实现的公开方法:
class mockA: public A{ public: // 原有其他mock定义 MOCK_METHOD0(functionB, bool()); // 新增:调用基类真实functionB的辅助方法 bool call_real_functionB() { return A::functionB(); } };
- 需要mock functionB的用例,保持你原来的写法即可:
TEST(test, testA_with_mock){ mockA objA; EXPECT_CALL(objA, functionB()).WillOnce(Return(true)); // 后续逻辑走mock返回值 }
- 不需要mock、要走基类真实逻辑的用例,通过
ON_CALL设置默认动作调用真实实现即可:
TEST(test, testA_no_mock){ mockA objA; // 所有functionB调用默认走基类真实逻辑 ON_CALL(objA, functionB()) .WillByDefault(Invoke(&objA, &mockA::call_real_functionB)); // 后续业务逻辑调用functionB时,和使用原生A类对象行为完全一致 }
注意:如果没有给mock方法设置任何EXPECT_CALL/ON_CALL,GMock默认会返回对应类型的默认值(bool类型默认返回false),不会自动调用基类的真实实现,必须显式设置Invoke动作才会走原逻辑。
方案2:mock类构造时加开关控制默认行为
如果不想在每个不需要mock的用例里重复写ON_CALL逻辑,可以给mock类加构造参数控制默认行为:
class mockA: public A{ public: /** * 构造函数 * @param use_real_funcB 为true时functionB默认走基类真实实现,为false时走默认mock逻辑 */ explicit mockA(bool use_real_funcB = false) { if (use_real_funcB) { ON_CALL(*this, functionB()) .WillByDefault(Invoke(this, &mockA::call_real_functionB)); } } MOCK_METHOD0(functionB, bool()); bool call_real_functionB() { return A::functionB(); } };
使用时只需要在构造对象时传入参数即可:
// 需要mock的用例 TEST(test, testA_with_mock){ mockA objA; // 默认use_real_funcB为false,正常设置EXPECT_CALL即可 EXPECT_CALL(objA, functionB()).WillOnce(Return(true)); } // 不需要mock的用例 TEST(test, testA_no_mock){ mockA objA(true); // 传入true,默认走真实逻辑,不需要额外写ON_CALL }
这种方式代码复用率更高,后续如果需要在走真实逻辑的用例里临时mock某次调用,直接写EXPECT_CALL覆盖默认动作即可,灵活性不受影响。
你之前考虑的新建两个内容几乎一致的mock类的方案不推荐,会产生大量冗余代码,后续基类接口变更时需要同步修改两处,维护成本很高。
内容的提问来源于stack exchange,提问作者code3
相关产品推荐
相关产品推荐

