我在使用谷歌模拟进行专门验证时遇到了问题。
让我们说,我已经模拟了这样一个函数:
MOCK_METHOD1( FuncName, void( ClassType const& ) );
(不要关心模拟声明本身)
我想对FuncName寄予期望,即调用方式 一个Function,它考虑其他参数来验证ClassType的实例是否有效:
bool const VerifyIntegrity( ClassType const& Obj, int const& param1, int const& param2 )
{
if( param1 == Obj.member1 && param2 == Obj.member2 ) return true;
return false;
}
这实际上是伪代码,真正的实现使用模板(可推导)和枚举,但这个例子应该足够了。 那么,如何在呼叫期望内调用VerifyItegrity(...)?
EXPECT_CALL( Mock, FuncName( _ ) ).WillOnce( ...???? );
基本上,问题是我如何在调用期望中显式选择一个参数,并通过调用任意函数(签名)来使用它。
我不想做的是编写一个比较操作符(不需要到现在为止)并创建匹配的参考对象,因为它们的数量太多(排列)。
提前致谢 - 所有回复都表示赞赏! :)
答案 0 :(得分:1)
当我看到你对RA的评论时,我认为你真的想要使用自定义动作,所以我完全重写了答案。我完整地留下了原始答案(关于在预期时间修正论点),因为它对其他人也有帮助。自定义操作允许您使用Google Mock手段创建函数对象,而不是使用std::bind
或lambdas手动声明它们。像这样使用它:
在顶层(不在TEST或夹具类内)
ACTION_P2(VerifyIntegrity, param1, param2)
{
EXPECT_EQ(param1, arg0.member1);
EXPECT_EQ(param2, arg0.member2);
}
然后您希望使用
进行通话EXPECT_CALL(Mock, FuncName(_)).
WillOnce(VerifyIntegrity(2.0, "hello"));
模拟函数的参数(在本例中为FuncName
)将作为arg0
,arg1
等传递到您在ACTION_P2中编写的代码块。在您之后,ACTION_P2是肯定是一个宏,它定义了一个具有模板成员函数的模板类,因此arg0
到argN
具有mock函数参数的类型(可能总是作为引用),而{{1}的类型}和param1
是从你在EXPECT_CALL子句中写的常量param2
和2.0
中推导出来的。
如果C ++ 11可用,您可以使用"hello"
来修复参数:
std::bind
另一种方式,如果VerifyIntegrity非常简单,就像你在问题中所做的那样,不是使用这样的函数,而是使用Google Mock匹配器语言对此验证进行编码:
using testing::Truly;
using namespace std::placeholders;
EXPECT_CALL(Mock, FuncName(Truly(std::bind(VerifyIntegrity, _1, 0, 100))));
它具有Google Mock能够说明预期的字段值与找到的值之间的优势。在这两个领域。
答案 1 :(得分:0)
除非我在您的用例中遗漏了某些内容,否则RA建议使用自定义匹配器将完全按照您的意愿执行操作。例如:
MATCHER_P2(ClassTypeMatches, m1, m2, "") {
return arg.member1 == m1 && arg.member2 == m2;
}
TEST(StackOverflow, CustomMatcher) {
MockThing thing;
EXPECT_CALL(thing, FuncName(ClassTypeMatches(1, 2)));
ClassType ct;
ct.member1 = 1;
ct.member2 = 2;
thing.FuncName(ct);
}
如果这不是您正在寻找的内容,请为您要完成的内容提供更多细节。