set EXPECT_CALL to redirect the call to the original method
Asked Answered
T

2

11

I have a class with several methods that depend on each other. Lets say foo(), bar() and baz().

When I test bar() I need to mock the behavior of foo(), when I test baz() I need to mock the behavior of bar().

If I mock bar for baz I cannot use the same mock class to test bar with the mocked foo().

My question is can I set EXPECT_CALL to actually call the original behavior and how. This will eliminate the need to create several Mock classes.

Thursby answered 28/8, 2014 at 19:30 Comment(0)
X
13

Answer can be found in gMock Cookbook.

In short, you need to write

class MockFoo : public Foo {
public:
  // Mocking a pure method.
  MOCK_METHOD(void, Pure, (int n), (override));
  // Mocking a concrete method.  Foo::Concrete() is shadowed.
  MOCK_METHOD(int, Concrete, (const char* str), (override));
};

and

ON_CALL(foo, Concrete).WillByDefault([&foo](const char* str) {
  return foo.Foo::Concrete(str);
});

or

EXPECT_CALL(foo, Concrete).WillOnce([&foo](const char* str) {
  return foo.Foo::Concrete(str);
});
Xerography answered 12/2, 2015 at 1:44 Comment(0)
K
2

You can do this without adding any extra methods, with an unusual call syntax: obj.Parent::method() or ptr->Parent::method().

For example:

struct Foo
{
    virtual int bar() const { return 42; }
};

struct MockFoo : public Foo
{
    MOCK_CONST_METHOD0(bar, int());
};

TEST(Demo, mock_can_call_parent)
{
    MockFoo mock;
    EXPECT_CALL(mock, bar()).WillOnce([&mock](){ 
        return mock.Foo::bar(); // trick is here
    });

    EXPECT_EQ(mock.bar(), 42);
}
Karilla answered 3/4, 2020 at 14:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.