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

Tamás Szelei picture Tamás Szelei · Oct 14, 2015 · Viewed 16k times · Source

I have two unit tests that share some state (unfortunately I can't change this since the point is to test the handling of this very state).

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
}

If I run the tests separately, both are successful. If I run them in the order test1, test2, I will get the following error in 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

The expectation that fails is the one in test1. The call does take place, but I would like to tell GoogleMock to not care after test1 is complete (in fact, I only want to check expectations in a test while the test is running).

I was under the impression that RetiresOnSaturation would do this, but with it I get:

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

Which I have to admit, confuses me. What does it mean? How can I solve this?

Answer

PiotrNycz picture PiotrNycz · Oct 19, 2015

You can read in documentation of Mock almost literally described your case:

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.

So you shall not expect, that at the end of the test case, in some magic way expectations will be "deactivated". As cited above - the mock destructor is the point of verification.

In your case - you mocks are not local variable - they are created in dynamic memory (heap in cited doc) and kept in your tested code via SubscribeToFooCallsGlobal(), So for sure mock created in one test is still alive in next test.

The easy, and proper solution is to unsubscribe at the end of each TC - I do not know if you have any UnsubscribeToFooCallsGlobal() - if not - create such function. To be sure that it will be always called - use ScopeGuard pattern.

There is one function to manually enforce verification Mock::VerifyAndClearExpectations(&mock_object) - but use it only if you need this verification not in the last line of your testcase, because that should be point of destruction.

edit: Fixed the googlemock link.