I am mocking a class with two overloaded methods like this:
//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));
};
In a test I am doing something like this (the code is not optimal but I am trying to understand what's going on and probably EXPECT_CALL is better here but I am trying to understand):
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;
});
}
where Matcher
must be used apparently in overloading cases. Also I had to specify the return value of the lambda with ->bool
.
The original function is called in this way:
shared_pointer_castom->foo({
{
defined_char_array,
static_cast<uint32_t>(someVal)
},
{
defined_car_array2,
static_cast<uint32_t>(someOtherVal)
}]
});
By debugging the code, I see it is running and the first MOCk_METHOD is correctly called. After that I get a null pointer exception in the gtest, precisely in /loki/loki-dev-env/Orin/01_linux64/include/gtest/gtest-matchers.h:269:: Condition vtable_ != nullptr failed.
(it does not enter the ON_CALL lambda). The code is the following:
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);
}
...
I guess I am not using correctly ON_CALL and Matcher. How to use ON_CALL together with Matcher to test an overloaded method?
According to gmock cookbook, testing::Matcher
shall be used to wrap your matcher, e.g.:
exact match of some testing data:
std::vector<KeyValueType> testData;
ON_CALL(mock, foo(testing::Matcher<const std::vector<std::pair<char*, uint32_t>>&>(testData)))
testing for some elements presence:
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::Contains(pair1))))
But if you simply want to disambiguate the call and you want to match against any value, you can simply use testing::An
:
ON_CALL(mock, foo(testing::An<const std::vector<std::pair<char*, uint32_t>>&>()))
Finally, your example doesn't need any of those tricks, because your overloaded foo
take different number of arguments, so simple:
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;
});
is enough.
Note: in my examples for simplicity I used MockSUT mock;
and a trivial implementation of struct SUT
.