如何忽略gtest中的第一个动作DoAll()

时间:2018-05-29 22:10:23

标签: c++ reference googletest gmock

我声明了一个函数

void MyFunction(const std::wstring& inParameter, std::wstring& outParamater);

第一个参数是传入参数,第二个参数是值out参数,函数我想要获取的值将通过outParameter传递出来。

现在我Gockock

MOCK_METHOD2(MyFunction, void(const std::wstring&, std::wstring&));

但是,当我使用这个模拟函数时:

std::wstring firstStr = L"firstStr";
std::wstring test = L"test";
EXPECT_CALL(*myGmockInstance, MyFunction(firstStr, _)).Times(1).WillOnce(DoAll(firstStr, SetArgReferee<1>(test)));

它不起作用。

我也试过

EXPECT_CALL(*myGmockInstance, MyFunction(_, _)).Times(1).WillOnce(DoAll(_, SetArgReferee<1>(test)));

EXPECT_CALL(*myGmockInstance, MyFunction(_, _)).Times(1).WillOnce(DoAll(firstStr, SetArgReferee<1>(test)));

EXPECT_CALL(*myGmockInstance, MyFunction(_, _)).Times(1).WillOnce(DoAll(SetArgReferee<0>(firstStr), SetArgReferee<1>(test)));

我了解inParameterconst,因此我无法使用SetArgReferee。但是如何设置它的值,同时我可以为outParameter设置值?

1 个答案:

答案 0 :(得分:0)

我认为你问题的标题很容易引起误解。根据我的理解,您只想为函数的第二个参数(输出参数)分配一些任意值。这是您使用Invoke

执行此操作的方法
using ::testing::_;

void assignStringToArg(const std::wstring&, std::wstring& outputStr,
    const std::wstring expectedStr) {
    outputStr = expectedStr;
}

class SomeMock {
public:
    MOCK_METHOD2(MyFunction, void(const std::wstring&, std::wstring&));
};

TEST(xxx, yyy) {
    SomeMock someMock;
    std::wstring firstStr(L"aaabbbccc");
    std::wstring secondStr(L"I should change upon MyFunction call ...");
    std::wstring expectedSecondStr(L"xxxyyyzzz");
    EXPECT_CALL(someMock, MyFunction(firstStr, _)).Times(1).WillOnce(Invoke(std::bind(
        &assignStringToArg,
        std::placeholders::_1,
        std::placeholders::_2,
        expectedSecondStr)));
    someMock.MyFunction(firstStr, secondStr);
    ASSERT_EQ(expectedSecondStr, secondStr);
}

请注意,提供给Invoke的函数必须与您希望调用的函数具有相同的签名(这就是我使用bind的原因)。您可以使用Google宏ACTION_P获得相同的结果。我更喜欢使用Invoke,因为它对我来说看起来更干净。

由于您的案例非常简单,您也可以像之前尝试过的那样使用SetArgReferee

    EXPECT_CALL(someMock, MyFunction(firstStr, _)).Times(1).WillOnce(
        SetArgReferee<1>(L"something"));
    someMock.MyFunction(firstStr, secondStr);
    ASSERT_EQ(L"something", secondStr);

如果你只想做一个动作,我认为没有必要使用DoAll。但是......如果你真的坚持:

    EXPECT_CALL(someMock, MyFunction(firstStr, _)).Times(1).WillOnce(
        DoAll(SetArgReferee<1>(L"something1"), SetArgReferee<1>(L"something2")));
    someMock.MyFunction(firstStr, secondStr);
    ASSERT_EQ(L"something2", secondStr);

这是一个相当愚蠢的例子,因为它将输出变量设置为L"something1",然后立即设置为L"something2"