Search code examples
c++unit-testinggoogletestgooglemock

Can I use google mocks to check method parameters without setting an expectation in advance?


I have a situation where I want to check if a mock object method was called with parameter X, but the test gets access to X only after the mock is invoked, so I can't set an EXPECT_CALL beforehand.

E.g.

// The class I'm testing.
class Maker
{
    void register(Listener& lis);
    Obj& make()
    {
        // make new Obj o
        // call created(o) on registered Listener  
        // return o
    }
}

class Listener
{
    virtual void created(Obj& o) = 0;
}

// The test
Listener lis;
Maker maker;
maker.register(lis);

Obj& o = maker.make();

// Check that lis was invoked using param o...how?

Can i do this with google mocks? What is the most elegant / readable way of doing this using google mocks?

Obviously I can make my own MockListener which will record invocation parameters, instead of using google mocks. But I'm hoping google mocks would preesnt a more readable mechanism, similar to EXPECT_CALL.


Solution

  • You can use the SaveArg<N> action to save the value of the parameter with which Listener::created(Obj&) is called, so you can compare its value to the one returned by maker.make() afterwards.

    This will require that you provide equality operator for class Obj, i.e. bool operator==(const Obj&, const Obj&).

    Your test could then look like this:

    class ListenerMock : public Listener
    {
    public:
        MOCK_METHOD1(created, void(Obj&));
    };
    
    TEST(MakerTest, make_registersObject)
    {
        ListenerMock lis;
        Maker maker;
        maker.register(lis);
    
        Obj createdArg;
        EXPECT_CALL(lis, created(_))
            .Times(1)
            .WillOnce(SaveArg<0>(&createdArg));
    
        Obj& o = maker.make();
    
        ASSERT_EQ(createdArg, o);
    }