Reputation: 869
Given the following mock method
MOCK_METHOD2(send, int(const void* pBuffer, size_t szBuffer));
And the following usage
EXPECT_CALL(socketMock, send(_, _))
.Times(1)
.WillOnce(ReturnArg<1>());
Will generate a warning in ReturnArg due to the implicit conversion of szBuffer into the return type of int.
Here's an example of code:
#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();
}
Here's the compiler warning:
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)
Is there anyway to make GMock use a static_cast to change the return type to eliminate the type conversion warning?
Upvotes: 2
Views: 1130
Reputation: 4620
ReturnArg<k>
is a Google Mock "action" (reference) that returns the k
th argument of the function being mocked. Since in this case, the return type of the function is int
and the first argument is of type size_t
, a warning about a potentially narrowing warning is generated.
The easiest way to inject an explicit typecast is to write a custom action:
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));
}
The action can be used this way:
...
.WillOnce(ReturnArgWithTypeCast<1, int>())
Upvotes: 3