使用 gmock Matchers 将 std::function 设置为 EXPECT_CALL 中的方法参数
Using gmock Matchers to set std::function as method argument inside EXPECT_CALL
正在尝试对 class
的私有回调方法进行单元测试
class MyClass{
public:
MyClass(Component& component) : component(component) {};
void Init();
private:
void callback();
Component component;
}
void MyClass::callback(const std::string& text)
{
...
}
使用我可以模拟的组件成员(component.register() 方法)在 public 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&)>));
按照这里的建议
我想 EXPECT_CALL 的 component.register() 函数,并使用 SaveArg 在单元测试局部变量中存储传递的 std::function<> 参数。
然后使用该变量我应该能够调用回调进行测试。
由于 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>&)'
...
是的,这通常是正确的方法,但是您发布的代码存在一些问题。首先,您为 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
作为函数名。
正在尝试对 class
的私有回调方法进行单元测试class MyClass{
public:
MyClass(Component& component) : component(component) {};
void Init();
private:
void callback();
Component component;
}
void MyClass::callback(const std::string& text)
{
...
}
使用我可以模拟的组件成员(component.register() 方法)在 public 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&)>));
按照这里的建议
由于 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>&)'
...
是的,这通常是正确的方法,但是您发布的代码存在一些问题。首先,您为 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
作为函数名。