使用 gmock c++ 在真实对象上调用方法
Invoke method on real object with gmock c++
我用 gmock 从一个对象中模拟了一个函数。现在我想要的是,每次调用此函数时,它都会调用对象 A 的函数,将 Param 作为参数传递。
您可以在下面找到代码片段
//class I want to call
class A {
public:
void func1(const Param& p) {cout<<p.name_<<endl;};
}
class Param {
public:
string name_;
}
class IMock {
public:
virtual void func2(int x) = 0;
}
class Mock : public IMock{
public:
MOCK_METHOD(void, func2, (int x), (override));
}
测试:
A a;
Param param;
Mock mock;
EXPECT_CALL(mock, func2(_))
.WillOnce(
testing::WithArg<param>(testing::Invoke(&a, a.func1)));
但是我有以下编译错误:
param 的值不能用于常量表达式
非静态成员函数virtual void的无效使用A::func1(const Param&)
有什么想法吗?
编辑 1
根据@pptaszni 的回复,新的测试代码是:
TEST(Test_case, test_flow) {
A a;
Param param;
Mock mock;
ON_CALL(mock, func2(_)).WillDefault(testing::Invoke(
[&a, ¶m]() { a.func1(param); })));
mock.func2(23);
}
但现在编译器说:
no matching function for call to testing::internal::OnCallSpec::WillByDefault(std::decay >::type)
[&a, & param]() { a.func1(param); }));
note: candidate: testing::internal::OnCallSpec& testing::internal::OnCallSpec::WillByDefault(const testing::Action&) [with F = void(int)]
OnCallSpec& WillByDefault(const Action& action) {
^~~~~~~~~~~~~
note: no known conversion for argument 1 from ‘std::decay >::type {aka Test_case_test_flow::TestBody()::}’ to ‘const testing::Action&’
我在 GitHub (1.10)
上使用最新版本的 googletet
我总是在 Invoke
中使用 lambda 表达式,因为恕我直言,这是最灵活的方法。
TEST(xxx, yyy)
{
A a;
Param param;
Mock mock;
EXPECT_CALL(mock, func2())
.WillOnce(Invoke([&a, ¶m]()
{
a.func1(param);
}));
mock.func2();
}
如果您不想传递对 a
和 param
的引用,您可以创建一个测试夹具,将它们声明为受保护的夹具字段并将 this
传递给 lambda 捕获阻止。
请注意,lambda 表达式必须与您的 Mock::func2
签名相同。在此示例中,它接受 0 个参数。
还有,你写了
every time this function is called
在这种情况下最好使用
ON_CALL(mock, mocked_method(/*params*/)).WillByDefault(Invoke(/*rest of the code*/));
特别是如果您有测试夹具并且可以在夹具的构造函数(或 SetUp
)中配置此默认操作。
我用 gmock 从一个对象中模拟了一个函数。现在我想要的是,每次调用此函数时,它都会调用对象 A 的函数,将 Param 作为参数传递。 您可以在下面找到代码片段
//class I want to call
class A {
public:
void func1(const Param& p) {cout<<p.name_<<endl;};
}
class Param {
public:
string name_;
}
class IMock {
public:
virtual void func2(int x) = 0;
}
class Mock : public IMock{
public:
MOCK_METHOD(void, func2, (int x), (override));
}
测试:
A a;
Param param;
Mock mock;
EXPECT_CALL(mock, func2(_))
.WillOnce(
testing::WithArg<param>(testing::Invoke(&a, a.func1)));
但是我有以下编译错误:
param 的值不能用于常量表达式
非静态成员函数virtual void的无效使用A::func1(const Param&)
有什么想法吗?
编辑 1
根据@pptaszni 的回复,新的测试代码是:
TEST(Test_case, test_flow) {
A a;
Param param;
Mock mock;
ON_CALL(mock, func2(_)).WillDefault(testing::Invoke(
[&a, ¶m]() { a.func1(param); })));
mock.func2(23);
}
但现在编译器说:
no matching function for call to testing::internal::OnCallSpec::WillByDefault(std::decay >::type) [&a, & param]() { a.func1(param); })); note: candidate: testing::internal::OnCallSpec& testing::internal::OnCallSpec::WillByDefault(const testing::Action&) [with F = void(int)] OnCallSpec& WillByDefault(const Action& action) { ^~~~~~~~~~~~~ note: no known conversion for argument 1 from ‘std::decay >::type {aka Test_case_test_flow::TestBody()::}’ to ‘const testing::Action&’
我在 GitHub (1.10)
上使用最新版本的 googletet我总是在 Invoke
中使用 lambda 表达式,因为恕我直言,这是最灵活的方法。
TEST(xxx, yyy)
{
A a;
Param param;
Mock mock;
EXPECT_CALL(mock, func2())
.WillOnce(Invoke([&a, ¶m]()
{
a.func1(param);
}));
mock.func2();
}
如果您不想传递对 a
和 param
的引用,您可以创建一个测试夹具,将它们声明为受保护的夹具字段并将 this
传递给 lambda 捕获阻止。
请注意,lambda 表达式必须与您的 Mock::func2
签名相同。在此示例中,它接受 0 个参数。
还有,你写了
every time this function is called
在这种情况下最好使用
ON_CALL(mock, mocked_method(/*params*/)).WillByDefault(Invoke(/*rest of the code*/));
特别是如果您有测试夹具并且可以在夹具的构造函数(或 SetUp
)中配置此默认操作。