如何在 gmock Expect_call 中对结构参数进行部分匹配

2023-11-30

struct obj
{
  int a;
  string str;
  string str2;
  bool operator==(const obj& o) const
  {
     if(a == o.a && str == o.str && str2 == o.str2) return true;
     return false;
   } 
}

然后在类中的函数中,它使用 struct 对象作为输入参数:

bool functionNeedsToBeMocked(obj& input)
{
  //do something
}

现在我想做的是,

EXPECT_CALL(*mockedPointer, functionNeedsToBeMocked( /* if input.a == 1 && input.str == "test" && input.str2.contains("first")*/  )).Times(1).WillOnce(Return(true));

输入值为

inputFirst.a = 1;
inputFirst.str = "test";
inputFirst.str2 = "something first";

我希望 inputFirst 可以与我的 EXPECT_CALL 匹配。

我如何使用 EXPECT_CALL 匹配器来做到这一点?

我确实看到了

EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")),
                      NULL));

在 gmock 食谱上,但我不知道如何对结构参数执行 HasSubStr 。


您可以实现自己的匹配器obj struct.

当您输入:

EXPECT_CALL(*mockedPointer, functionNeedsToBeMocked(some_obj)).Times(1).WillOnce(Return(true));

然后 gmock 使用默认匹配器,Eq, using some_obj作为其预期参数和实际参数functionNeedsToBeMocked论证为arg在匹配器中。Eq匹配器将默认调用bool operator==对于预期对象和实际对象:

EXPECT_CALL(*mockedPointer, functionNeedsToBeMocked(Eq(some_obj))).Times(1).WillOnce(Return(true));

但是,由于您不想使用bool operator==,您可以编写一个自定义匹配器(删除Times(1)因为它也是默认的):

// arg is passed to the matcher implicitly
// arg is the actual argument that the function was called with
MATCHER_P3(CustomObjMatcher, a, str, str2, "") {
  return arg.a == a and arg.str == str and (arg.str2.find(str2) != std::string::npos); 
}
[...]
EXPECT_CALL(*mockedPointer, functionNeedsToBeMocked(CustomObjMatcher(1, "test", "first"))).WillOnce(Return(true));

可以使用 来编写自定义匹配器Field匹配器和内置匹配器为HasString但让我们“把它作为练习留给读者”:P

更新:完整的代码Field匹配器:

struct obj {
    int a;
    std::string str;
    std::string str2;
};

struct Mock {
    MOCK_METHOD(bool, functionNeedsToBeMocked, (obj&));
};

// creates a matcher for `struct obj` that matches field-by-field
auto Match(int expected_a, std::string expected_str1, std::string expected_substr2) {
    return testing::AllOf(
            testing::Field(&obj::a, expected_a),
            testing::Field(&obj::str, expected_str1),
            testing::Field(&obj::str2, testing::HasSubstr(expected_substr2))
    );
}

TEST(MyTest, test) {
    Mock mock{};

    obj inputFirst;
    inputFirst.a = 1;
    inputFirst.str = "test";
    inputFirst.str2 = "something first";

    EXPECT_CALL(mock, functionNeedsToBeMocked(Match(1, "test", "first"))).Times(1).WillOnce(Return(true));

    mock.functionNeedsToBeMocked(inputFirst);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 gmock Expect_call 中对结构参数进行部分匹配 的相关文章

随机推荐