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
相关产品推荐
相关产品推荐

