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

GMock是否允许为不同Mock对象交错设置期望与调用?

关于gMock期望设置与Mock调用顺序的疑问

根据gMock官方文档中的提示:

重要提示:gMock要求在调用Mock函数前设置期望,否则行为未定义。请勿交替调用EXPECT_CALL()和Mock函数,且在将Mock传递给API后,不得再对其设置任何期望。

我不确定该要求是针对单个Mock对象,还是测试中所有Mock对象?我想知道是将所有Mock调用放在测试末尾更安全,还是可以按逻辑拆分,先处理一个Mock的期望+调用,再处理另一个?

更新:
即,是否可以这样编写测试代码:

TEST_F(MySuite, MyTest)
{
    Mock mock1, mock2;
    ObjToTest obj{mock1, mock2};

    EXPECT_CALL(mock1, foo);
    obj.funcCallingFooOnMock1();

    EXPECT_CALL(mock2, bar);
    obj.funcCallingBarOnMock2();
}

还是这样属于未定义行为(UB),必须改为:

TEST_F(MySuite, MyTest)
{
    Mock mock1, mock2;
    ObjToTest obj{mock1, mock2};

    EXPECT_CALL(mock1, foo);
    EXPECT_CALL(mock2, bar);

 
    obj.funcCallingFooOnMock1();
 
    obj.funcCallingBarOnMock2();
}

解答

gMock的这条规则是针对单个Mock对象的,而非测试中所有Mock对象。

你提供的第一种写法完全合法,不属于未定义行为,原因如下:

  • 对mock1而言,先设置EXPECT_CALL(mock1, foo),再调用触发它的obj.funcCallingFooOnMock1(),顺序完全符合要求
  • 对mock2而言,同样是先设置期望,再调用对应的方法,没有违反规则

规则中“请勿交替调用EXPECT_CALL()和Mock函数”的核心限制,是同一个Mock对象不能出现「调用Mock方法→设置该Mock的期望→再调用该Mock方法」这类交叉顺序。比如以下两种写法才属于违规:

违规示例1:调用Mock方法后才设置期望

TEST_F(MySuite, BadTest)
{
    Mock mock1;
    ObjToTest obj{mock1};

    obj.funcCallingFooOnMock1(); // 先调用mock1的foo,未提前设置期望
    EXPECT_CALL(mock1, foo);    // 违反规则:调用Mock函数后才设置期望
}

违规示例2:同一个Mock对象的期望与调用交替进行

TEST_F(MySuite, BadTest)
{
    Mock mock1;
    ObjToTest obj{mock1};

    EXPECT_CALL(mock1, foo);
    obj.funcCallingFooOnMock1();
    EXPECT_CALL(mock1, foo); // 已调用过mock1的方法后,又给该Mock设置新期望
    obj.funcCallingFooOnMock1();
}

如果按逻辑拆分能让测试代码更清晰,完全可以采用第一种写法,不需要强制把所有期望提前一次性设置完毕。


内容的提问来源于stack exchange,提问作者JenyaKh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 20:23:30