I have an interface
class IUObject {
public:
virtual void setProperty(const std::string& name, const std::any& value) = 0;
virtual void setProperty(const std::string& name, std::any&& value) = 0;
};
I`ve created mock object:
class MockUObject : public IUObject {
public:
MOCK_METHOD(void, setProperty, (const std::string& name, const std::any& value), (override));
MOCK_METHOD(void, setProperty, (const std::string& name, std::any&& value), (override));
};
I need to test setProperty
function via EXPECT_CALL
.
I`ve tried something like this:
MockUObject *mock = new MockUObject();
/// Some code here
EXPECT_CALL(*mock, setProperty(TypedEq<const std::string&>("position"),
TypedEq<std::any&&>(std::any(std::pair<double, double>(6.0, 2.0)))));
But compiler cant compare std::any
:
error: no match for 'operator==' (operand types are 'const std::any' and 'const std::any')
I cant change base interface functions, so i have to work with std::any
. How can i deal with this problem?
CodePudding user response:
AFAIK, there is no matcher for std::any
, so you need to write your own.
MATCHER_P(AnyMatcher, value, "")
{
// assume the type of parameter is the same as type stored in std::any,
// will not work e.g. when any stores std::string and you pass a literal
// you'd need to write a template matcher for that case
return std::any_cast<decltype(value)>(arg) == value;
}
Usage:
EXPECT_CALL(*mock, setProperty(TypedEq<const std::string&>("position"),
AnyMatcher(std::pair<double, double>(6.0, 2.0))));
See it online (and a passing case). Note that you cannot really have overloads where one function has const
lvalue reference as argument and the other rvalue reference, because that's ambiguous (both can accept rvalue as argument).