如何在 gtest 中使用 ON_CALL 和 Matcher 以及重载的模拟 nfunctions?

问题描述 投票:0回答:1

我正在用两个重载方法来模拟一个类,如下所示:

//required because some versions of gtest messes with extra commas in MOCK_METHOD
typedef std::pair<char*, uint32_t>  KeyValueType;
class MockSUT : public SUT
{
public:

    MOCK_METHOD(bool, foo, (const std::vector<KeyValueType> &data), (override));
 
    MOCK_METHOD(bool, foo, (const std::string &key, const std::string& data), (override));
};

在测试中我正在做这样的事情(代码不是最优的,但我试图理解发生了什么,可能 EXPECT_CALL 在这里更好,但我试图理解):

TEST_F(fixture, test)
{
  ...
  std::shared_ptr<Mocksut> mock = std::make_shared<MocksSUT>();
  ON_CALL(..,..); //on call on another mock that succeds

  ON_CALL(*mock.get(), foo(::testing::Matcher<const std::vector<std::pair<char*, uint32_t>>&>()))
      .WillByDefault([&](const std::vector<std::pair<char*, uint32_t>>& data)-> bool{
        EXPECT_TRUE(true);
        return true;
  });
}

其中

Matcher
显然必须在过载情况下使用。我还必须用
->bool
指定 lambda 的返回值。

原来的函数是这样调用的:

shared_pointer_castom->foo({
  { 
    defined_char_array, 
    static_cast<uint32_t>(someVal)
  }, 
  { 
    defined_car_array2, 
    static_cast<uint32_t>(someOtherVal)
  }]
});

通过调试代码,我看到它正在运行并且第一个 MOCk_METHOD 被正确调用。之后,我在 gtest 中得到一个空指针异常,正是在

/loki/loki-dev-env/Orin/01_linux64/include/gtest/gtest-matchers.h:269:: Condition vtable_ != nullptr failed. 
中(它没有进入 ON_CALL lambda)。代码如下:

template <typename T>
class MatcherBase : private MatcherDescriberInterface {
 public:
  // Returns true if and only if the matcher matches x; also explains the
  // match result to 'listener'.
  bool MatchAndExplain(const T& x, MatchResultListener* listener) const {
    GTEST_CHECK_(vtable_ != nullptr);
    return vtable_->match_and_explain(*this, x, listener);
  }
...

我想我没有正确使用 ON_CALL 和 Matcher。如何使用 ON_CALL 和 Matcher 一起测试重载方法?

c++ overloading googletest vtable
1个回答
0
投票

根据gmock Cookbook

testing::Matcher
应用于包装你的匹配器,例如:

部分测试数据完全匹配:

std::vector<KeyValueType> testData;
ON_CALL(mock, foo(testing::Matcher<const std::vector<std::pair<char*, uint32_t>>&>(testData)))

测试某些元素的存在:

std::vector<KeyValueType> testData;
char rawText[] = "xxx";
auto pair1 = std::make_pair(rawText, uint32_t(69));
testData.push_back(pair1);
testData.push_back(pair1);
ON_CALL(mock, foo(testing::Matcher<const std::vector<std::pair<char*, uint32_t>>&>(testing::ElementsAre(pair1))))

但是,如果您只是想消除调用的歧义并且想要匹配任何值,则可以简单地使用

testing::An
:

ON_CALL(mock, foo(testing::An<const std::vector<std::pair<char*, uint32_t>>&>()))

最后,您的示例不需要任何这些技巧,因为您的重载

foo
采用不同数量的参数,如此简单:


ON_CALL(mock, foo(testing::_))
    .WillByDefault([&](const auto& data) { // note, no need to explicitly specify args and return types
        EXPECT_TRUE(true);  // note, it's not a classic approach to expect things inside mock callbacks; better to test the observable effects
        return true;
    });

就够了。

© www.soinside.com 2019 - 2024. All rights reserved.