GMock 在使用 ReturnArg 时删除隐式转换警告

GMock removing implicit conversion warning when using ReturnArg

给出以下模拟方法

MOCK_METHOD2(send, int(const void* pBuffer, size_t szBuffer));

以及下面的用法

EXPECT_CALL(socketMock, send(_, _))
    .Times(1)
    .WillOnce(ReturnArg<1>());

由于 szBuffer 隐式转换为 return 类型的 int,将在 ReturnArg 中生成警告。

这是一个代码示例:

#include <cstddef>
#include <cstdint>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

class ISocket {
public:
    virtual int Send(const uint8_t* payload, const std::size_t payloadLength, std::size_t& sentLength) = 0;
};

class SocketMock : public ISocket {
public:
    MOCK_METHOD3(Send, int(const uint8_t*, const std::size_t, std::size_t&));
};

class MySender
{
public:
    static void Ping(ISocket& socket)
    {
        std::size_t bytesSent;
        uint8_t payload[64];
        memset(payload, 0, sizeof(payload));

        socket.Send(payload, sizeof(payload), bytesSent);

        if (bytesSent != sizeof(payload))
            throw std::runtime_error("Socket transmission failed");
    }
};

TEST(SocketSend, ReturnsBytesTransmitted)
{
    SocketMock socket;

    EXPECT_CALL(socket,
        Send(
            ::testing::_, // payload
            ::testing::_, // payload length
            ::testing::_  // return by param, bytes sent
        )).Times(1)
        .WillOnce(::testing::ReturnArg<1>());

    MySender::Ping(socket);

    ::testing::Mock::VerifyAndClearExpectations(&socket);
}

GTEST_API_ int main(int argc, char** argv)
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

这是编译器警告:

googletest\googlemock\include\gmock/gmock-more-actions.h(165): warning C4267: 'return': conversion from 'size_t' to 'int', possible loss of data (compiling source file TestMain.cpp)

有没有办法让 GMock 使用 static_cast 更改 return 类型以消除类型转换警告?

ReturnArg<k> 是一个 Google 模拟“动作”(reference),return 是被模拟函数的第 k 个参数。由于在这种情况下,函数的 return 类型为 int 并且第一个参数的类型为 size_t,因此会生成有关可能缩小警告的警告。

注入显式类型转换的最简单方法是编写自定义操作:

    ACTION_TEMPLATE(ReturnArgWithTypeCast,
        HAS_2_TEMPLATE_PARAMS(int, k, typename, return_type),
        AND_0_VALUE_PARAMS()) {
        return static_cast<return_type>(::testing::get<k>(args));
    }

动作可以这样使用:

...
.WillOnce(ReturnArgWithTypeCast<1, int>())