Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 816
nappyfalcon Avatar asked Sep 30 '15 18:09

nappyfalcon


1 Answers

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])
like image 153
Piotr Skotnicki Avatar answered Sep 27 '22 19:09

Piotr Skotnicki