简体   繁体   中英

C++ GoogleMock mock method call within another method of the same class

I was looking at this question here: Can googlemock mock method calls from within other method calls of the same class?

and tried to implement the answer, however it does not work for me.

I have modified the link question implementation to remove the mock ReturnInputPlus1() which is what the accepted answer suggests:

using ::testing::Invoke;
using ::testing::_;
using ::testing::Return;

class MyClass
{
  public:
    MyClass() : x(1) {}
    virtual ~MyClass() {}

    int ReturnInput(int x) { return x; }
    int ReturnInputPlus1(int x) { return ReturnInput(x) + 1; }
  private:
    int x;
};

class MockMyClass : public MyClass
{
public:
    MockMyClass()
    {
        ON_CALL(*this, ReturnInput(_)).WillByDefault(Invoke(&real, &MyClass::ReturnInput));
    }
    virtual ~MockMyClass() {}

    MOCK_METHOD1(ReturnInput, int(int y));

private:
    MyClass real;
};

TEST(MyClassTest, mockUseClassMethod)
{
    MockMyClass mock;

    EXPECT_CALL(mock, ReturnInput(_))
        .WillOnce(Return(2));

    EXPECT_EQ(3, mock.ReturnInputPlus1(1));
}

This still returns the same failure

/projects/tests/cpp/google-test/test.cpp:46: Failure
      Expected: 3
To be equal to: mock.ReturnInputPlus1(1)
      Which is: 2
/projects/tests/cpp/google-test/test.cpp:41: Failure
Actual function call count doesn't match EXPECT_CALL(mock, ReturnInput(_))...
         Expected: to be called once
           Actual: never called - unsatisfied and active

I do not see a way to achieve the redirection of the internal call to the mock behaviour without making the methods in MyClass virtual .

Below is a working example:

  • Removed the real member, the mock is inheriting MyClass anyway
  • I guess the 'trick' is to know that one can call parent class behaviour like this: mock.MyClass::ReturnInputPlus1(1) ( qualified name lookup ) and to understand that dynamic dispatch will cause the usage of MockMyClass::ReturnInput.
  • I am not too sure what MyClass::x wanted to achieve since it will be shadowed by the function parameters.

class MyClass
{
public:
    MyClass()
        : m_x(1)
    {
    }
    virtual ~MyClass() {}

    virtual int ReturnInput(int x) { return x; }
    virtual int ReturnInputPlus1(int x) { return ReturnInput(x) + 1; }

private:
    int m_x;
};

class MockMyClass : public MyClass
{
public:
    MockMyClass()
        : MyClass()
    {
        ON_CALL(*this, ReturnInput(_)).WillByDefault(Invoke(this, &MyClass::ReturnInput));
    }
    virtual ~MockMyClass() {}

    MOCK_METHOD1(ReturnInput, int(int y));
    MOCK_METHOD1(ReturnInputPlus1, int(int y));
};

TEST(MyClassTest, mockUseClassMethod)
{
    MockMyClass mock;

    EXPECT_CALL(mock, ReturnInput(_)).WillOnce(Return(2));

    EXPECT_EQ(3, mock.MyClass::ReturnInputPlus1(1));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM