How to mock method with optional parameter in Google Mock?
Asked Answered
Q

4

23

How to mock a method with optional parameter in Google Mock? For example:

class A
{ 
public:
    void set_enable( bool enabled = true );
};

class MockA : public A
{
    MOCK_METHOD1( set_enable, void( bool ) );    // this is not working
};
Quart answered 21/7, 2016 at 9:30 Comment(0)
P
32

This is an alternative of Marko's answer: If you don't want to change your original code, just implement the helper in the mock class:

class A
{ 
public:
    virtual void set_enable( bool enabled = true );
};

class MockA : public A
{
    MOCK_METHOD1( set_enable_impl, void( bool ) );
    virtual void set_enable( bool enabled = true )
    {
        set_enable_impl( enabled );
    }
};

You still have to expect calls of set_enable_impl in your tests, for example

MockA mockA;
EXPECT_CALL(mockA, set_enable_impl(true)).Times(Exactly(1));
EXPECT_CALL(mockA, set_enable_impl(false)).Times(Exactly(1));
Propraetor answered 12/7, 2017 at 6:7 Comment(1)
This should be the correct answer. The whole purpose of default parameters is avoiding extraneous overloaded methods in the production code.Shred
D
6

Change implementation of your method set_enable to use a helper method, like this:

void set_enable( bool enabled = true ) { set_enable_impl(enabled); }

Now, in class MockA, create a mock method for set_enable_impl:

MOCK_METHOD1( set_enable_impl, void( bool ) );

Then, in your production code you simply use set_enable as you would in the first place, while in tests you can set expectations on method set_enable_impl:

MockA mockA;
EXPECT_CALL(mockA, set_enable_impl(_))...;

An alternative would be to overload the method by having versions with one and zero parameters. It is up to you to determine which way works better for your case.

Denbighshire answered 21/7, 2016 at 9:53 Comment(3)
It would have been better if there was no change to the original code just for test purpose. By the way I'll accept your answer as the best one if there will not be any other way.Quart
@Quart There is an alternative, but it also requires changing the original code. See my updated answer.Denbighshire
@Quart Consider marking the answer as accepted if you did not find a better solution, or if you did then please share it with us.Denbighshire
S
5

Some modifications to PiQuer's answer. You wouldn't need a wrapper if just add the name, "enabled" to the variable of type bool in your MOCK_METHOD1 like below:

class A
{ 
    public:
    void set_enable( bool enabled = true );
};

class MockA : public A
{
    MOCK_METHOD1( set_enable, void( bool enabled ) );
};
Seepage answered 17/11, 2019 at 23:17 Comment(1)
I think this answer makes more sense nowadays!Laboured
U
0

Set two mocks like this:

class MockA : public A
{
    MOCK_METHOD1( set_enable, void( bool ) );
    MOCK_METHOD1( set_enable, void( ) );
};
Understanding answered 11/11, 2021 at 9:43 Comment(1)
In this case we get compiller error error: static_assert failed due to requirement '::testing::tuple_size<std::tuple<>>::value == 1' "This method does not take 1 arguments. Parenthesize all types with unprotected commas."Paly

© 2022 - 2024 — McMap. All rights reserved.