Объявляю функцию
void MyFunction(const std::wstring& inParameter, std::wstring& outParamater);
Первый параметр - это переданный параметр, второй - параметр выходного значения, значение, которое я хочу получить с помощью функции, передаст его с помощью 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?





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