Using Google Mocks, how to give a mock implementation without caring about / setting any expectation of invocation

nappyfalcon picture nappyfalcon · Sep 30, 2015 · Viewed 12.8k times · Source

I have an interface class say:

class MyInterface
{
public:
    virtual int doThing(int x, int y, int z) = 0;
};

I want to write a mock implementation for use in my tests. E.g.Traditionally, without using Google Mocks, I would write say:

class MyMock : public MyInterface
{
public:
    virtual int doThing(int x, int y, int z)
    {
        if (x == 1)
            return y + z;
        else
            return y - z;
    }
};

How would I do this in google mocks. Please note, I don't want to (Ok, I don't need to) set an expectation about how this mock is called. I'm just using it to test something else.

How would you do it (and what is the most clearest way)? I find the google mocks documentation a little too concise to figure this out.

Answer

Piotr Skotnicki picture Piotr Skotnicki · Sep 30, 2015

Include the Google Mock header file:

#include <gmock/gmock.h>

Declare a mock class:

struct MyMock : MyInterface
{
    MOCK_METHOD3( doThing, int(int x, int y, int z) );
};

Instantiate the mock as a NiceMock (it won't issue any warning upon an unregistered call):

testing::NiceMock<MyMock> mock;

Bring the anything matcher to the scope:

using testing::_;

Define default behavior with ON_CALL rather than EXPECT_CALL using one of the below options:

Option #1

Hard-code a default return value:

ON_CALL( mock, doThing(_,_,_) ).WillByDefault(testing::Return(0));
//                                     default return value ~~^

Option #2

Delegate the call to a global function:

int foo(int x, int y, int z)
{
    if (x == 1)
        return y + z;
    else
        return y - z;
}

ON_CALL( mock, doThing(_,_,_) ).WillByDefault(testing::Invoke(foo));

Option #3

Delegate the call to a lambda expression (C++11):

ON_CALL( mock, doThing(_,_,_) ).WillByDefault(testing::Invoke(
    [] (int x, int y, int z)
    { 
        if (x == 1)
            return y + z;
        else
            return y - z;
    }
));

Option #4

Build a lambda expression with the Boost.Lambda library:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/if.hpp>

using namespace boost::lambda;

ON_CALL( mock, doThing(_,_,_) ).WillByDefault(testing::Invoke(
    ret<int>(if_then_else(_1 == 1, _2 + _3, _2 - _3))
));

// or: ret<int>(if_(_1 == 1)[_2 + _3].else_[_2 - _3])