如何从调用期望中调用比模拟方法更多参数的函数

how to invoke a function taking more arguments than the mock-method from within a call-expectation

我在使用 google 模拟进行专用验证时遇到问题。

比方说,我模拟了这样一个函数:

MOCK_METHOD1( FuncName, void( ClassType const& ) );

(不关心模拟声明本身)

我想寄希望于FuncName,调用方式 一个函数,它验证 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( ...???? );

基本上,问题是我如何显式 select 调用期望中的参数并通过调用 arbitrary 函数(签名)来使用它。

我不想做的是编写比较操作(到目前为止不需要)和创建匹配的参考对象,因为它们的数量太多(排列)。

提前致谢 - 感谢所有回复! :)

我看到你对 RA 的评论,我认为你真的想使用自定义操作,所以我完全重写了答案。我原封不动地保留了原始答案(关于在预期时间确定论点),因为它也可能对其他人有帮助。自定义操作允许您使用 Google Mock 方法创建函数对象,而不是使用 std::bind 或 lambda 手动声明它们。像这样使用它:

在顶层(不在 TEST 或夹具内 class)

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 作为 arg0arg1 等传递到您在 ACTION_P2 中编写的代码块中。在你背后,ACTION_P2 肯定是一个宏,它定义了一个模板 class ,它有一个模板成员函数,所以 arg0argN 有模拟函数参数的类型(可能总是作为参考),而 param1param2 的类型是根据您在 EXPECT_CALL 子句中编写的常量 2.0"hello" 推导出来的。


如果 C++11 可用,您可以使用 std::bind 来修复参数:

using testing::Truly;
using namespace std::placeholders;
EXPECT_CALL(Mock, FuncName(Truly(std::bind(VerifyIntegrity, _1, 0, 100))));

另一种方式,如果 VerifyIntegrity 真的像您在问题中所做的那样简单,则不是使用这样的函数,而是使用 Google 模拟匹配器语言编写此验证:

using ::testing::AllOf;
using ::testing::Field;
EXPECT_CALL(Mock, FuncName(AllOf(
                    Field(&ClassType::member1, 0),
                    Field(&ClassType::member2, 9))));

它的优点是 Google Mock 能够明确说明期望的字段值与找到的值。在这两个领域。

除非我在这里遗漏了您的用例中的某些内容,否则 RA 关于使用自定义匹配器的建议将完全符合您的要求。例如:

MATCHER_P2(ClassTypeMatches, m1, m2, "") {

    return arg.member1 == m1 && arg.member2 == m2;
}

TEST(Whosebug, CustomMatcher) {

    MockThing thing;
    EXPECT_CALL(thing, FuncName(ClassTypeMatches(1, 2)));

    ClassType ct;
    ct.member1 = 1;
    ct.member2 = 2;
    thing.FuncName(ct);
}

如果这不是您要查找的内容,请提供更多关于您要完成的内容的具体信息。