如何在单个测试用例的InSequence中覆盖ON_CALL默认行为?
问题描述
在单元测试的SetUp方法中,通过ON_CALL(mock, GetNumofChild()).WillByDefault(Return(2))为mock方法设置了默认返回值。期望在TestGetValue测试用例的testing::InSequence代码块内,用EXPECT_CALL(mock, GetNumofChild()).WillOnce(Return(10))覆盖默认行为,但实际运行时该方法仍返回ON_CALL设置的2,不符合预期。
相关代码:
SetUp代码
void SetUp() { ON_CALL(mock, GetNumofChild()).WillByDefault(Return(2)); /*other on_call defaults*/ }
测试用例代码
TEST_F(Testing, TestGetValue){ { testing::InSequence seq; /* other expect_call */ EXPECT_CALL(mock, GetNumofChild()).WillOnce(Return(10)); /* other expect_call */ } Foo(); }
运行结果
uint8 u8NumOfChild = m_obj.GetNumofChild(); // Result: u8NumOfChild equal to 2, result by ON_CALL // Expected: u8NumOfChild equal to 10, overridden by EXPECT_CALL
排查与解决方法
1. 确认mock对象一致性
检查SetUp中配置的mock实例和测试用例里调用的m_obj是否为同一个对象。如果m_obj不是配置了ON_CALL/EXPECT_CALL的mock实例,所有期望都不会生效,自然返回默认值。
- 修正:确保测试中调用的对象就是目标mock实例。
2. 严格匹配调用顺序
InSequence的核心作用是约束mock方法的调用顺序,要求代码块内的EXPECT_CALL声明顺序必须与Foo()内部的实际调用顺序完全一致。如果GetNumofChild()的调用时机与InSequence内的期望顺序不符,会导致匹配失败,触发默认行为。
- 修正:按照
Foo()的实际执行流程,调整InSequence内EXPECT_CALL的排列顺序。
3. 匹配调用次数与期望设置
如果GetNumofChild()在Foo()中被调用多次,而仅声明了WillOnce(Return(10)),只有第一次调用会返回10,后续调用会使用默认值。若需要多次返回指定值,可改为WillRepeatedly(Return(10))或添加多个WillOnce。
- 示例修正:
EXPECT_CALL(mock, GetNumofChild()).WillRepeatedly(Return(10));
4. 调整作用域限制
将InSequence和EXPECT_CALL移出局部代码块,直接放在测试用例顶层。局部代码块销毁时InSequence对象seq会被回收,可能导致顺序约束提前失效,影响期望匹配。
- 修正后的测试用例:
TEST_F(Testing, TestGetValue){ testing::InSequence seq; /* other expect_call */ EXPECT_CALL(mock, GetNumofChild()).WillOnce(Return(10)); /* other expect_call */ Foo(); }
内容的提问来源于stack exchange,提问作者JWg

