如何忽略 gtest DoAll() 中的第一个动作
How to ignore the first action in the gtest DoAll()
我声明一个函数
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"
。
我声明一个函数
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"
。