c++ Gmock匹配结构

cl25kdpy  于 2022-12-24  发布在  其他
关注(0)|答案(5)|浏览(118)

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

struct SomeStruct
    {   
        int data1;
        int data2; 
    };

    void SomeMethod(SomeStruct data);

我怎样才能匹配这个方法的模拟调用与正确的值在参数?

syqv5f0l

syqv5f0l1#

在详细阅读了Google模拟文档之后,我解决了定义匹配器一节中记录的问题。(如果有一个例子就太好了!)
因此解决方案是使用MATCHER_P宏来定义一个自定义匹配器。因此,对于匹配的SomeStruct.data1,我定义了一个匹配器:

MATCHER_P(data1AreEqual, ,"") { return (arg.data1 == SomeStructToCompare.data1); }

为了在期望中匹配它,我使用了如下的自定义宏:

EXPECT_CALL(someMock, SomeMethod(data1AreEqual(expectedSomeStruct)));

这里,expectedSomeStruct是我们所期望的structure.data1的值。
请注意,正如其他答案(在这篇文章和其他文章中)所建议的,它需要被测单元进行修改以使其可测试。这应该是没有必要的!

t1qtbnec

t1qtbnec2#

如果需要显式地测试一个struct的一个字段(或一个类的一个“属性”)的特定值,gmock有一个简单的方法可以通过“Field”和“Property”定义来测试。

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

或者,如果我们有SomeClass(代替SomeStruct),它有私有成员变量和公共getter函数:

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

rseugnpd3#

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 matcher根据成员变量的值来匹配参数(如果一个测试对比较结构体示例之间的相等性感兴趣,那么这就很好地表明其他代码也会感兴趣,所以可能只需要定义一个operator==就可以了)。

jqjz2hbq

jqjz2hbq4#

这个问题很久以前就已经回答过了,也许没有用,但这里有一个解决方案,它适用于任何结构,不使用MATCHER或FIELD。
假设我们正在检查:方法名称(常量Foo和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);
    });
bqf10yzr

bqf10yzr5#

这基本上是回答以上,但我想给予你一个更好的例子:

// 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)));

相关问题