10

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.

273K
  • 29,503
  • 10
  • 41
  • 64
gsf
  • 6,612
  • 7
  • 35
  • 64

2 Answers2

12

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);
});
Wieland
  • 1,663
  • 14
  • 23
Haozhun
  • 6,331
  • 3
  • 29
  • 50
1

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);
}
ricab
  • 2,697
  • 4
  • 23
  • 28