【问题标题】:Gmock - matching structuresGmock - 匹配结构
【发布时间】:2014-05-29 16:30:48
【问题描述】:

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

    struct SomeStruct
    {   
        int data1;
        int data2; 
    };

    void SomeMethod(SomeStruct data);

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

【问题讨论】:

  • 您的意思是将SomeStruct 定义为联合吗?
  • 是的,对不起结构或联合,有可能吗?

标签: c++ gmock


【解决方案1】:

在详细阅读了 Google 模拟文档后,我解决了我在 Defining Matchers 部分中记录的问题。 (一个例子会很棒!)

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

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

为了符合预期,我使用了这个自定义宏,如下所示:

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

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

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

【讨论】:

  • 是的,非常同意 - gmock 备忘单很棒,除非您想实际看到一个示例,这通常是找出要做什么的最好/最简单的方法。您的示例 MATCHER 这正是帮助我解决问题的原因!
  • 嗨,请告诉我如何模拟一个方法 methodx(param1* p1,param1* p2,tm * tm1) 和 tm 结构中的测试值“tm_isdst”为 0。我想知道如何编写一个马歇尔
【解决方案2】:

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

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

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

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

【讨论】:

    【解决方案3】:

    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;
        }
    };
    

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

    【讨论】:

    • 那行不通!我不会问它是否这么简单!
    • 你能澄清你的意思,它“不起作用”吗?发布不起作用的代码,以便我们提供更好的指导。
    • 试试看 - 你会得到“没有找到二进制 == 运算符”,因为没有办法比较结构!
    • 抱歉——出于某种原因,我认为 C++ 为 POD 类型生成了一个默认的相等运算符。我会更新我的答案。
    • 很公平。我练习 TDD,所以我的测试总是影响我的设计。
    【解决方案4】:

    也许没用,因为很久以前就已经回答了这个问题,但这里有一个适用于任何结构且不使用 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);
        });
    

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多