提问者:小点点

对lambda的模拟成员函数调用


使用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)>&

共1个答案

匿名用户

gmock的错误消息可能有些神秘,当您处理的类型是基本类型的typedef时,它对您没有帮助; 在本例中为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-限定符)void(uint8_t)uint8_t(uint8_t)的“on call spec”不匹配。