You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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逻辑:

  1. 先在mock类中补充调用基类真实实现的公开方法:
class mockA: public A{
    public:
        // 原有其他mock定义
        MOCK_METHOD0(functionB, bool());

        // 新增:调用基类真实functionB的辅助方法
        bool call_real_functionB() {
            return A::functionB();
        }
};
  1. 需要mock functionB的用例,保持你原来的写法即可:
TEST(test, testA_with_mock){
    mockA objA;
    EXPECT_CALL(objA, functionB()).WillOnce(Return(true));
    // 后续逻辑走mock返回值
}
  1. 不需要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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 10:36:38