Gmock - 匹配结构

Nil*_*ose 10 c++ gmock

如何为输入参数匹配union中元素的值,例如 - 如果我使用以下符号模拟方法 -

    struct SomeStruct
    {   
        int data1;
        int data2; 
    };

    void SomeMethod(SomeStruct data);
Run Code Online (Sandbox Code Playgroud)

如何在参数中使用正确的值调用此方法的模拟?

Nil*_*ose 19

在详细阅读了Google模拟文档之后,我解决了我在定义匹配器部分中记录的问题.(一个例子会很棒!)

因此,解决方案是使用MATCHER_P宏来定义自定义匹配器.所以对于匹配SomeStruct.data1我定义了一个匹配器:

MATCHER_P(data1AreEqual, ,"") { return (arg.data1 == SomeStructToCompare.data1); }
Run Code Online (Sandbox Code Playgroud)

为了满足它的期望我使用这个自定义宏像这样:

EXPECT_CALL(someMock, SomeMethod(data1AreEqual(expectedSomeStruct)));
Run Code Online (Sandbox Code Playgroud)

在这里,expectedSomeStructstructure.data1我们期待的价值.

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

  • 是的,大家都同意-gmock备忘单很棒,除非您想实际看到一个实际的例子,这通常是弄清楚该怎么做的最好/最简单的方法。您以“ MATCHER”为例,这正是帮助我解决问题的原因! (2认同)

小智 8

如果只需要显式测试结构的一个字段(或类的一个“属性”)的特定值,则gmock有一种简单的方法可以使用“字段”和“属性”定义进行测试。使用结构:

EXPECT_CALL( someMock, SomeMethod( Field( &SomeStruct::data1, expectedValue )));
Run Code Online (Sandbox Code Playgroud)

或者,如果我们有SomeClass(SomeStruct的中间部分),则它具有私有成员变量和公共getter函数:

EXPECT_CALL( someMock, SomeMethod( Property( &SomeClass::getData1, expectedValue )));
Run Code Online (Sandbox Code Playgroud)


Lil*_*ste 6

Google提供了一些关于使用gmock的完整文档,其中包含示例代码.我强烈建议您查看它:

https://github.com/abseil/googletest/blob/master/googlemock/docs/CookBook.md#using-matchers

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

    // Assumes `SomeMethod` is mocked in `MockedObject`
    MockedObject foo;
    SomeStruct expectedValue { 1, 2 };

    EXPECT_CALL(foo, SomeMethod(expectedValue));
Run Code Online (Sandbox Code Playgroud)

因此,最直接的处理方法是为结构定义一个等于运算符:

struct SomeStruct
{   
    int data1;
    int data2; 

    bool operator==(const SomeStruct& rhs) const
    {
        return data1 == rhs.data1
            && data2 == rhs.data2;
    }
};
Run Code Online (Sandbox Code Playgroud)

如果您不想使用该路径,可以考虑使用Field匹配器根据其成员变量的值匹配参数.(如果测试有兴趣比较结构实例之间的相等性,那么它很好地表明其他代码也会感兴趣.因此,定义一个operator==并完成它可能是值得的.)


BWD*_*BWD 5

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

假设我们正在检查:methodName(const 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);
    });
Run Code Online (Sandbox Code Playgroud)