How to Mock the return object

余生颓废 提交于 2021-01-07 03:08:57

问题


I try to mock a User class and its nested struct UserBuilder:

class User
{
  public:
        virtual int loadData(const std::string& filename);
        virtual UserBuilder getUserBuilder(const std::string& functionName) const;

        struct UserBuilder
       {
        UserBuilder(std::string functionName) : m_functionName{functionName} {};
        virtual ~UserBuilder();
        virtual UserBuilder& fun1();
        virtual UserBuilder& fun2(int32_t num);
        virtual bool callFunction();
       private:
        std::string m_functionName{};
      };
}

This is the mock class for User:

class UserMock : public User
{
public:
    MOCK_METHOD1(loadData, int(const std::string& filename));
    MOCK_CONST_METHOD1(getUserBuilder, UserBuilder(const std::string& functionName));
};

Thsi is the mock class for UserBuilder:

struct UserBuilderMock : public User::UserBuilder
{
public:
    UserBuilderMock(std::string functionName) : User::UserBuilder(functionName) {}
    MOCK_METHOD0(fun1, UserBuilder&());
    MOCK_METHOD1(fun2, UserBuilder&(int32_t num));
    MOCK_METHOD0(callFunction, bool());
};

I want to test this function:

void useCase(std::unique_ptr<User> userP)
{   
    int status = userP->loadFile("init");
    if (status == 0)
    {
        User::UserBuilder builder = userP->getUserlBuilder("init");
        bool result = builder.fun1().fun2(1).callFunction();
        return result;
    }
    else
    {
        return false;
    }
}

I give the getUserBuilder("init") a mock object builderMock as its return value, like this:

auto userMock = std::make_unique<UserMock>();
ON_CALL(*userMock, loadFile("init")).WillByDefault(Return(0));
UserBuilderMock builderMock("init");
EXPECT_CALL(*userMock, getUserBuilder("init")).WillOnce(ReturnPointee(&builderMock));
EXPECT_CALL(builderMock,fun1()).Times(1);

The test log fail: fun1 never called-unsatisfied and active. I want to use the builderMock object to call the mock method fun1,fun2 and callFunction, but it still use the real UserBuilder object call the real fun1,fun2 and callFunction. What should I do to make it use Mock object call the Mock method?


回答1:


You have to rewrite your code to make User::getUserBuilder return a pointer (possibly smart one) to UserBuilder.

With the method returning UserBuilder object

EXPECT_CALL(*userMock, getUserBuilder("init")).WillOnce(ReturnPointee(&builderMock));

getUserBuilder casts the mock to an object of its base class (slicing), losing all the the mock additions.



来源:https://stackoverflow.com/questions/59983087/how-to-mock-the-return-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!