我有两个单元测试共享一些状态(不幸的是我无法改变这一点,因为重点是测试处理这个状态)。
TEST(MySuite, test1)
{
shared_ptr<MockObject> first(make_shared<MockObject>());
SubscribeToFooCallsGlobal(first);
EXPECT_CALL(*first, Foo(_));//.RetiresOnSaturation();
TriggerFooCalls(); // will call Foo in all subscribed
}
TEST(MySuite, test2)
{
shared_ptr<MockObject> second(make_shared<MockObject>());
SubscribeToFooCallsGlobal(second);
EXPECT_CALL(*second, Foo(_)).Times(1);
TriggerFooCalls(); // will call Foo in all subscribed
}
如果我单独运行测试,两者都是成功的。如果我在test1,test2的命令中运行它们,我将在 test2 中收到以下错误:
mytest.cpp(42): error: Mock function called more times than expected - returning directly. Function call: Foo(0068F65C) Expected: to be called once Actual: called twice - over-saturated and active
失败的期望是test1中的期望。电话确实发生了,但我想在test1
完成后告诉GoogleMock 不在乎(事实上,我只想在测试运行时检查测试中的期望)
我的印象是RetiresOnSaturation
会这样做,但我得到了:
Unexpected mock function call - returning directly. Function call: Foo(005AF65C) Google Mock tried the following 1 expectation, but it didn't match: mytest.cpp(42): EXPECT_CALL(first, Foo(_))... Expected: the expectation is active Actual: it is retired Expected: to be called once Actual: called once - saturated and retired
我不得不承认,让我感到困惑。这是什么意思?我该如何解决这个问题?
答案 0 :(得分:6)
你可以阅读documentation of Mock几乎完全描述过你的案例:
强制验证
当它被驱逐时,您的友好模拟对象将自动进行 验证对它的所有期望是否已经满足,并且会 如果没有,则生成Google测试失败。离开时很方便 你少担心一件事。也就是说,除非你不是 确定你的模拟物体是否会被摧毁。
你的模拟对象最终不会被销毁怎么可能? 好吧,它可能是在堆上创建的,并且由您所拥有的代码拥有 测试。假设该代码中存在错误,并且不会删除该代码 模拟对象正确 - 你最终可能会通过测试 实际上有一个错误。
所以你不能指望,在测试案例结束时,以某种神奇的方式期望将被“停用”。如上所述 - 模拟析构函数是验证点。
在你的情况下 - 你的模拟不是局部变量 - 它们是在动态内存中创建的(引用文档中的堆)并通过SubscribeToFooCallsGlobal()
保存在测试代码中,所以确保在一次测试中创建的模拟仍然存在在下一次测试中。
简单而恰当的解决方案是在每个TC结束时取消订阅 - 我不知道你是否有UnsubscribeToFooCallsGlobal()
- 如果没有 - 创建这样的功能。为了确保它始终被调用 - 使用ScopeGuard pattern。
有一个功能可以手动强制执行验证Mock::VerifyAndClearExpectations(&mock_object)
- 但只有在您不需要在测试用例的最后一行中进行此验证时才使用它,因为这应该是破坏点。