我正在用两个重载方法来模拟一个类,如下所示:
//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 一起测试重载方法?
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;
});
就够了。