使用gmock Matchers将std :: function设置为EXPECT_CALL中的方法参数

时间:2018-03-20 16:33:24

标签: c++ unit-testing googlemock gmock

尝试单元测试类的私有回调方法

class MyClass{
public:
 MyClass(Component& component) : component(component) {};
 void Init();
private:
 void callback();
 Component component;
}

void MyClass::callback(const std::string& text)
{
...
}

使用我可以模拟的组件成员(component.register()方法)在公共Init方法中注册回调。

void MyClass::Init(){
   auto cb = std::bind(&MyClass::callback, this, std::placeholders::_1);
   connection = component.register(ESomeType::MyType, std::move(cb));
}

MOCK_METHOD2(register, boost::signals2::connection(ESomeType, std::function<void(const std::string&)>));

如此处所示 How to unit test the std::bind function using gtest? 我想要一个component.register()函数的EXPECT_CALL并存储传递的std :: function&lt;&gt;使用SaveArg在单元测试局部变量中的参数。 然后使用该变量,我应该能够为测试目的调用回调。

由于component.register()是重载函数,我需要使用Matchers将精确的参数类型传递给EXPECT_CALL以避免歧义。

不幸的是,设置匹配器类型时出现问题。

当前测试代码:

ComponentMock component;
MyClass testClass(component);

std::function <void(const std::string& text)> componentCallback;

EXPECT_CALL(component, register(Matcher<ESomeType>(ESomeType::MyType),
                          Matcher< void(const std::string& text) >(componentCallback)))
                          .WillOnce(testing::SaveArg<1>(&componentCallback;);

testClass.init();

testClass.componentCallback( ... );

首先是正确的方法吗?如果是的话,你能否帮我解决以下错误:

In file included from gmock-generated-function-mockers.h:43:0, gmock.h:61, ComponentMock.hpp:16, Test.cpp:18:
In member function 'void Test_initialize()':
Test.cpp: error: no matching function for call to 'testing::Matcher<void(const std::basic_string<char>&)>::Matcher(std::function<void(const std::basic_string<char>&)>&)'
                                  Matcher< void(const std::string& string) >(componentCallback)));
                                                                                        ^
...
gmock-matchers.h:3747:1: note: candidate: testing::Matcher<T>::Matcher(T) [with T = void(const std::basic_string<char>&)]
 Matcher<T>::Matcher(T value) { *this = Eq(value); }
 ^~~~~~~~~~
gmock-matchers.h:3747:1: note:   no known conversion for argument 1 from 'std::function<void(const std::basic_string<char>&)>' to 'void (*)(const std::basic_string<char>&)'
...

1 个答案:

答案 0 :(得分:1)

是的,这通常是正确的方法,但您发布的代码存在一些问题。首先,您为Matcher指定的类型不正确(您忘记了std::function)。其次,std::function没有提供适当的相等运算符,因此您必须使用::testing::An而不是::testing::Matcher

解决这些问题,测试机构应该看起来像下面这样:

ComponentMock component;
MyClass testClass(component);

std::function <void(const std::string& text)> componentCallback;

EXPECT_CALL(component, register(Matcher<ESomeType>(ESomeType::MyType),
                          An< std::function<void(const std::string& text)>>()))
                          .WillOnce(testing::SaveArg<1>(&componentCallback;);

testClass.init();

testClass.componentCallback( ... );

另外,请避免使用register作为函数的名称。