我怎样才能告诉 GoogleMock 在测试完成后停止检查期望值?

How can I tell GoogleMock to stop checking an expectation after the test finished?

我有两个共享某些状态的单元测试(不幸的是我无法更改它,因为重点是测试这个状态的处理)。

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 not care(事实上,我只想在测试时检查测试中的期望是运行宁)。

我的印象是 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

我不得不承认,这让我很困惑。这是什么意思?我该如何解决这个问题?

您可以阅读 documentation of Mock 几乎字面描述您的情况:

Forcing a Verification

When it's being destoyed, your friendly mock object will automatically verify that all expectations on it have been satisfied, and will generate Google Test failures if not. This is convenient as it leaves you with one less thing to worry about. That is, unless you are not sure if your mock object will be destoyed.

How could it be that your mock object won't eventually be destroyed? Well, it might be created on the heap and owned by the code you are testing. Suppose there's a bug in that code and it doesn't delete the mock object properly - you could end up with a passing test when there's actually a bug.

所以你不应该期望,在测试用例结束时,期望会以某种神奇的方式被“停用”。如上所述 - 模拟析构函数是验证点。

在你的情况下 - 你的模拟不是局部变量 - 它们是在动态内存中创建的(引用文档中的堆)并通过 SubscribeToFooCallsGlobal() 保存在你测试的代码中,所以可以肯定的是在一个测试中创建的模拟是下次测试还活着。

简单而正确的解决方案是在每个 TC 结束时取消订阅 - 我不知道您是否有任何 UnsubscribeToFooCallsGlobal() - 如果没有 - 创建这样的功能。为确保它将始终被调用 - 使用 ScopeGuard pattern.

有一个函数可以手动强制执行验证 Mock::VerifyAndClearExpectations(&mock_object) - 但仅当您需要此验证时才使用它,而不是在测试用例的最后一行,因为那应该是破坏点。

编辑:修复了 googlemock link.