模拟成员函数调用 lambda

Mock member function call to lambda

本文关键字:lambda 函数调用 成员 模拟      更新时间:2023-10-16

使用 c++17 和 gmock,我正在模拟一个类,并希望将对其成员函数之一的调用重定向到 lambda。这可能吗?

他举个最小的例子:

#include <gmock/gmock.h>
using ::testing::_;
using ::testing::Invoke;
using ::testing::Return;
class Foo
{
public:
virtual uint8_t MyCall(const uint8_t in) const
{
return in;
}
};
class MockFoo : public Foo
{
public:
MOCK_METHOD(uint8_t, MyCall, (const uint8_t), (const, override));
};
TEST(MyTest, MyTestCase)
{
MockFoo mock_foo;
ON_CALL(mock_foo, MyCall(_)).WillByDefault(Invoke([](const uint8_t to) {
static_cast<void>(to);
}));
}

编译时出现以下错误:

demo.cpp: In member function 'virtual void MyTest_MyTestCase_Test::TestBody()':
demo.cpp:82:7: error: no matching function for call to 'testing::internal::OnCallSpec<unsigned char(unsigned char)>::WillByDefault(std::decay<MyTest_MyTestCase_Test::TestBody()::<lambda(uint8_t)> >::type)'
}));
^
In file included from external/gtest/googlemock/include/gmock/gmock-function-mocker.h:42:0,
from external/gtest/googlemock/include/gmock/gmock.h:61,
from demo.cpp:2:
external/gtest/googlemock/include/gmock/gmock-spec-builders.h:323:15: note: candidate: testing::internal::OnCallSpec<F>& testing::internal::OnCallSpec<F>::WillByDefault(const testing::Action<F>&) [with F = unsigned char(unsigned char)]
OnCallSpec& WillByDefault(const Action<F>& action) {
^~~~~~~~~~~~~
external/gtest/googlemock/include/gmock/gmock-spec-builders.h:323:15: note:   no known conversion for argument 1 from 'std::decay<MyTest_MyTestCase_Test::TestBody()::<lambda(uint8_t)> >::type {aka MyTest_MyTestCase_Test::TestBody()::<lambda(uint8_t)>}' to 'const testing::Action<unsigned char(unsigned char)>&
lambda 的返回类型

与成员函数的返回类型不匹配

gmock 的错误消息可能有些晦涩难懂,当您使用从 typedefs 到基本类型的类型时,它无济于事;在本例中uint8_t.

如果我们仔细观察错误消息:

错误:调用没有匹配函数

'testing::internal::OnCallSpec<unsigned char(unsigned char)>
::WillByDefault(std::decay<MyTest_MyTestCase_Test::TestBody()
::<lambda(uint8_t)> >::type)'

它实际上提供了一些提示:

  • unsigned char(unsigned char)OnCallSpec
  • 与提供的 (WillByDefault( 可调用的类型不匹配。

前者,在查看您的程序并在固定宽度的 typedefs 中手动翻译时,实际上告诉我们:

  • uint8_t(uint8_t)OnCallSpec

这使得默认可调用对象的类型(即 lambda(有问题变得更加明显。

在这种特殊情况下,lambda 的返回类型(隐式(是void,因此(忽略 CV 限定符(与uint8_t(uint8_t)的"随叫随到规范"void(uint8_t)不匹配。