Mocking destructor using Die() pattern causes "uninteresting mock" warnings, despite NiceMock

1,082 views
Skip to first unread message

Michael Dudley

unread,
May 10, 2013, 3:43:28 PM5/10/13
to googl...@googlegroups.com
I'm using googlemock 1.6.0 to set expectations on my class's destructor using the Die() pattern described in the cookbook. I've been using NiceMock to hide "uninteresting mock" warnings, but Die() brings them back.

The tests below demonstrate how

#include "gmock/gmock.h"
#include "gtest/gtest.h"

using ::testing::NiceMock;

struct MyObject {
    virtual ~MyObject() {}
    virtual void MyFunction() = 0;
};

struct MyObjectMock : public MyObject {
    virtual ~MyObjectMock() {}
    MOCK_METHOD0(MyFunction, void ());
};

struct MyDieObjectMock : public MyObject {
    virtual ~MyDieObjectMock() { Die(); }
    MOCK_METHOD0(Die, void ());
    MOCK_METHOD0(MyFunction, void ());
};

struct MyObjectTest : public ::testing::Test {};

TEST_F(MyObjectTest, NickMockPreventsUninterestingWarning) {
    // Uninteresting function warnings are suppressed here, as expected
    NiceMock<MyObjectMock> lMyObject;
    lMyObject.MyFunction();
}

TEST_F(MyObjectTest, CallToDieTriggersUninterestingWarning) {
    // Uninteresting function warning about Die gets raised here, but shouldn't
    NiceMock<MyDieObjectMock> lMyObject;
    lMyObject.MyFunction();
}

And just for completeness, the output I get is:

[----------] 2 tests from MyObjectTest
[ RUN      ] MyObjectTest.NickMockPreventsUninterestingWarning
[       OK ] MyObjectTest.NickMockPreventsUninterestingWarning (0 ms)
[ RUN      ] MyObjectTest.CallToDieTriggersUninterestingWarning

GMOCK WARNING:
Uninteresting mock function call - returning directly.
    Function call: Die()
Stack trace:
[       OK ] MyObjectTest.CallToDieTriggersUninterestingWarning (4 ms)
[----------] 2 tests from MyObjectTest (5 ms total)

I had expected the "uninteresting mock function" warning about Die() to be suppressed.

Thanks!

Vlad Losev

unread,
May 10, 2013, 11:23:48 PM5/10/13
to Google C++ Mocking Framework
I believe this is an artifact of how NiceMock is implemented. NiceMock<T> is a subclass of T, and when the T's destructor receives control, NiceMock's destructor has already exited, and the instance is no longer considered to be NiceMock, but T. When the Die invocation calls the virtual function that's to provide a reaction to the call, that will be T's version, not NiceMock's. Essentially, NiceMock loses its politeness in the destructor.

This is not easy to fix, and I suggest as a workaround you invoke EXPECT_CALL(lMyObject, die()).Times(AnyNumber()) in your test. Once you are ready to act on that call, add some conditions or actions to that expectation.


--
 
---
You received this message because you are subscribed to the Google Groups "Google C++ Mocking Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to googlemock+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Zhanyong Wan (λx.x x)

unread,
May 13, 2013, 12:32:37 PM5/13/13
to Vlad Losev, Google C++ Mocking Framework
Excellent analysis, Vlad!

Another option is to use a separate check point object instead of adding a Die() method on the mock itself:


Long term, we should make mocks nice by default and this will become a moot issue.
--
Zhanyong

Billy Donahue

unread,
May 13, 2013, 1:01:20 PM5/13/13
to Zhanyong Wan (λx.x x), Vlad Losev, Google C++ Mocking Framework
That would just be shifting the problem to the StrictMock and NaggyMock wrappers.

Zhanyong Wan (λx.x x)

unread,
May 13, 2013, 1:07:34 PM5/13/13
to Billy Donahue, Vlad Losev, Google C++ Mocking Framework
I meant that Michael's particular problem (which uses NiceMock) will become moot.
--
Zhanyong
Reply all
Reply to author
Forward
0 new messages