Как игнорировать первое действие в gtest DoAll () - PullRequest
0 голосов
/ 30 мая 2018

Я объявляю функцию

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

Первый параметр передается в параметре, второй - в параметре value out, значение, которое я хочу получить с помощью функции, передаст его на outParameter.

Теперь я Gmock это

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)));

Я понимаю, что inParameter это const, поэтому я не могу использовать SetArgReferee за это.Но как установить его значение и в то же время я могу установить значение для outParameter?

1 Ответ

0 голосов
/ 30 мая 2018

Я думаю, что название вашего вопроса вводит в заблуждение.Из того, что я понимаю, вы просто хотите присвоить какое-то произвольное значение второму аргументу вашей функции (выходной аргумент).Вот как вы можете сделать это, используя 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".

...