Googlemock如何分阶段控制Mock函数调用预期及禁止调用校验
实现方案
你可以通过以下两种常用的gmock特性实现分阶段控制mock调用的需求:
方案一:顺序预期 + 饱和退役机制
通过InSequence强制预期按定义顺序匹配,结合RetiresOnSaturation让单次预期满足后自动失效,再通过Times(0)禁止后续匹配的调用:
#include <gmock/gmock.h> using ::testing::InSequence; TEST(MyTest, MockCallControl) { MockObj mockObj; // 定义InSequence对象后,后续所有EXPECT_CALL按定义顺序匹配 InSequence seq; // 第一阶段:匹配参数为1的调用,允许1次 EXPECT_CALL(mockObj, targetFunc(1)).Times(1); foo(1); // 第二阶段:匹配参数为2的调用,仅允许1次,满足后自动退役不再参与匹配 EXPECT_CALL(mockObj, targetFunc(2)).Times(1).RetiresOnSaturation(); foo(2); // 第三阶段:禁止所有参数为2的调用,匹配到就直接报错 EXPECT_CALL(mockObj, targetFunc(2)).Times(0); foo(2); foo(2); // 第四阶段:匹配参数为3的调用,允许1次 EXPECT_CALL(mockObj, targetFunc(3)).Times(1); foo(3); }
如果使用StrictMock定义mock对象,第三阶段可以省略Times(0)的预期,未被匹配的调用会直接触发测试失败;如果使用默认的NiceMock,必须显式定义Times(0)才会拦截未预期的调用。
方案二:分阶段验证清空
如果阶段划分非常明确,可在每个阶段结束后手动验证并清除所有现有预期,实现阶段完全隔离:
#include <gmock/gmock.h> using ::testing::Mock; TEST(MyTest, MockCallControl) { MockObj mockObj; // 第一阶段 EXPECT_CALL(mockObj, targetFunc(1)).Times(1); foo(1); // 验证当前阶段预期全部满足,清空所有现有预期 Mock::VerifyAndClearExpectations(&mockObj); // 第二阶段 EXPECT_CALL(mockObj, targetFunc(2)).Times(1); foo(2); Mock::VerifyAndClearExpectations(&mockObj); // 第三阶段:显式禁止参数为2的调用 EXPECT_CALL(mockObj, targetFunc(2)).Times(0); foo(2); foo(2); Mock::VerifyAndClearExpectations(&mockObj); // 第四阶段 EXPECT_CALL(mockObj, targetFunc(3)).Times(1); foo(3); }
关键API说明
RetiresOnSaturation():预期的调用次数被满足后,该预期自动失效,不再参与后续调用匹配Times(0):明确禁止匹配该规则的调用,只要有符合规则的调用就直接触发测试失败InSequence:强制作用域内所有预期按定义的先后顺序匹配,避免gmock默认逆序匹配规则导致的异常匹配Mock::VerifyAndClearExpectations():手动验证指定mock对象的所有预期是否满足,满足后清空所有现有预期,不会影响后续新定义的预期
内容的提问来源于stack exchange,提问作者Rajeev Mehta
相关产品推荐
相关产品推荐

