Gmock -匹配结构

Gmock - matching structures

本文关键字:结构 -匹 Gmock      更新时间:2023-10-16

如何为输入参数匹配联合中的元素值,例如-如果我用以下签名模拟方法-

    struct SomeStruct
    {   
        int data1;
        int data2; 
    };
    void SomeMethod(SomeStruct data);

我如何匹配这个方法被调用的模拟与正确的参数值?

在详细阅读了Google模拟文档之后,我解决了定义匹配器一节中记录的问题。(举个例子就好了!)

因此,解决方案是使用MATCHER_P宏来定义自定义匹配器。所以对于匹配的SomeStruct.data1,我定义了一个匹配器:
MATCHER_P(data1AreEqual, ,"") { return (arg.data1 == SomeStructToCompare.data1); }
为了在期望中匹配它,我使用了这个自定义宏,像这样:
EXPECT_CALL(someMock, SomeMethod(data1AreEqual(expectedSomeStruct)));

这里,expectedSomeStruct是我们期望的structure.data1的值。

请注意,正如其他答案(在这篇文章和其他文章中)所建议的那样,它要求被测单元进行更改以使其可测试。这应该没有必要!如重载。

如果需要显式地测试结构体的一个字段(或一个属性)的特定值;(类),gmock有一个简单的方法来测试这一点,使用"Field"answers";Property"定义。使用struct:

EXPECT_CALL( someMock, SomeMethod( Field( &SomeStruct::data1, Eq(expectedValue) )));

或者,如果我们有someeclass(而不是SomeStruct),它有私有成员变量和公共getter函数:

EXPECT_CALL( someMock, SomeMethod( Property( &SomeClass::getData1, Eq(expectedValue) )));

Google提供了一些关于使用gmock的很好的文档,其中充满了示例代码。我强烈推荐你去看看:

https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md using-matchers

正如您所指出的,不会为类类型(包括pod)自动创建默认的相等操作符(==)。由于gmock在匹配参数时使用此操作符,因此您需要显式定义它,以便像使用任何其他类型一样使用该类型(如下所示):

    // Assumes `SomeMethod` is mocked in `MockedObject`
    MockedObject foo;
    SomeStruct expectedValue { 1, 2 };
    EXPECT_CALL(foo, SomeMethod(expectedValue));
因此,处理这个问题最直接的方法是为结构体定义一个相等操作符:
struct SomeStruct
{   
    int data1;
    int data2; 
    bool operator==(const SomeStruct& rhs) const
    {
        return data1 == rhs.data1
            && data2 == rhs.data2;
    }
};

如果你不想走那条路,你可以考虑使用Field匹配器根据参数成员变量的值来匹配参数。(但是,如果测试对比较结构体实例之间的相等性感兴趣,则很好地表明其他代码也会感兴趣。所以它可能是值得的,只是定义一个operator==,并完成它。)

也许没用,因为这个问题很久以前就已经回答了,但这里有一个解决方案,适用于任何结构,不使用MATCHER或FIELD。

假设我们正在检查:foo):

using ::testing::_;
struct Foo {
    ...
    ...
};
EXPECT_CALL(mockObject, methodName(_))
    .WillOnce([&expectedFoo](const Foo& foo) {
        // Here, gtest macros can be used to test struct Foo's members
        // one by one for example (ASSERT_TRUE, ASSERT_EQ, ...)
        ASSERT_EQ(foo.arg1, expectedFoo.arg1);
    });

上面基本上已经回答了这个问题,但我想再给你一个好例子:

// some test type
struct Foo {
    bool b;
    int i;
};
// define a matcher if ==operator is not needed in production
MATCHER_P(EqFoo, other, "Equality matcher for type Foo") {
    return std::tie(arg.b, arg.i) == std::tie(other.b, other.i);
}
// example usage in your test
const Foo test_value {true, 42};
EXPECT_CALL(your_mock, YourMethod(EqFoo(test_value)));