GMock std::any 参数

GMock std::any argument

我有接口

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

我已经创建了模拟对象:

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

我需要通过 EXPECT_CALL 测试 setProperty 功能。 我试过这样的事情:

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

但是编译器无法比较std::any:

error: no match for 'operator==' (operand types are 'const std::any' and 'const std::any')

我无法更改基本接口函数,所以我必须使用 std::any。我该如何处理这个问题?

据我所知,std::any 没有匹配器,因此您需要自己编写。

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

用法:

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)。请注意,在一个函数将 const 左值引用作为参数而另一个右值引用作为参数的情况下,您不能真正进行重载,因为这是不明确的(两者都可以接受右值作为参数)。