Search code examples
c++unit-testinggooglemock

Gmock only expect a specific call


I have a C++ class I am attempting to test with GMock. I have the following mock class:

class MyTestMock
{
    public:
        MOCK_METHOD1(myCoolMethod, int(const char*));
        MOCK_METHOD1(myCoolMethod, int(string));
}

Then in my test the following happens:

MyTestMock myMock;
if ( myMock.myCoolMethod("stuff") )
{
    // Stuff I don't care about, don't want to execute
}
if ( myMock.myCoolMethod("moarStuff") )
{
    // More stuff I don't care about, don't want to execute
}
if ( myMock.myCoolMethod("foo") )
{
    // This I care about and want to execute
}

What I would like to do is allow the first two calls to be uninteresting calls that return the default for integers, 0, while I set up a specific expectation on the third call to return 1. This was my attempt to do so:

EXPECT_CALL(myMock, myCoolMethod(TypedEq<const char *>("foo"))).WillOnce(Return(1));

However, this ends up making the test fail. If I do this instead:

EXPECT_CALL(myMock, myCoolMethod(Matcher<const char *>(_))).WillRepeatedly(Return(0));
EXPECT_CALL(myMock, myCoolMethod(TypedEq<const char *>("foo"))).WillOnce(Return(1));

my test passes fine. I am attempting to make unit testing as painless as possible on an old, massive, monolithic-style codebase, so I'd really like to not need the extra magic line to tell it to return the default value. Any ideas on how I can do this with just the one expectation without tanking my test?


Solution

  • I guess my answer is not very "expected" for testing "an old, massive, monolithic-style codebase" with possible huge numbers of such CoolMethods..., but, unfortunately this is how google-mock works. As you can read in their FAQ:

    Having an ON_CALL in the set-up part of a test doesn't mean that the calls are expected. If there's no EXPECT_CALL and the method is called, it's possibly an error. If we quietly let the call go through without notifying the user, bugs may creep in unnoticed.

    The same is with "default" ON_CALL - I mean when you did not write explicitly ON_CALL because default value for a type (in your case 0 for int) is perfectly OK.

    My advice is to always put such general expectation in SetUp function of your test suite - this way your test cases are not overloaded with many magic expectations:

    class MyTestSuite : public ::testing::Test
    {
    protected:
        MyTestMock myMock;
        void SetUp() override
        {
            EXPECT_CALL(myMock, myCoolMethod(Matcher<const char *>(_))).WillRepeatedly(Return(0));
        }   
    };
    

    This way you have "annoying" lines only in one place, and your test cases are "clear":

    TEST_F(MyTestSuite, shallDoSomethingWhenCoolMethodAcceptsFoo)
    {
       EXPECT_CALL(myMock, myCoolMethod(TypedEq<const char *>("foo"))).WillOnce(Return(1));
    }
    TEST_F(MyTestSuite, shallDoSomethingElseWhenCoolMethodAcceptsMoarStuff)
    {
       EXPECT_CALL(myMock, myCoolMethod(TypedEq<const char *>("moarStuff"))).WillOnce(Return(1));
    }