Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Mock : Setting argument in EXPECT_CALL

I am trying to set a class member function parameter value in Google Mock, but I get build errors and I simply don't understand what is going on. Would it be possible for someone to explain please.

The function prototype is:

virtual int recv( Socket socket
                , char *buffer
                , int bufferLength
                , int flags ) = 0;

I am trying to test it using:

TEST_F( IPV4SocketTests, Read_SockErr_ok )
{
    Mock_SocketAdaptor *adaptor = new Mock_SocketAdaptor;
    char *rcvBuffer = "testingRcvWorks";

    EXPECT_CALL( *adaptor, recv( testing::_, testing::_, testing::_, testing::_ ) )
    .WillRepeatedly( testing::DoAll(
        testing::SetArgPointee<1>( rcvBuffer ),
        testing::Return( strlen( rcvBuffer ) ) ) );

The error I am getting is regarding conversion from std::get.

like image 628
Gemma Morriss Avatar asked Feb 10 '16 10:02

Gemma Morriss


People also ask

What is difference between On_call and Expect_call?

If you are also in the habit of giving tests descriptive names that tell what they verify, you can often easily guess what's wrong just from the test log itself. So use ON_CALL by default, and only use EXPECT_CALL when you actually intend to verify that the call is made.

What is expect call in gMock?

In gMock we use the EXPECT_CALL() macro to set an expectation on a mock method. The general syntax is: EXPECT_CALL(mock_object, method(matchers)) . Times(cardinality) .

What is Googlemock?

Now known as the Googletest Mocking Framework, Google Mock is the standard mocking framework for C++ developers. What is the Googletest Mocking Framework used for? gMock is used for creating fake objects in order to remove external dependencies for effective testing.


1 Answers

The problem is that rcvBuffer is a pointer. That is why you must dereference it when setting the pointee. Here is how your EXPECT_CALL should look:

EXPECT_CALL( *adaptor, recv( testing::_, testing::_, testing::_, testing::_ ) )
    .WillRepeatedly( testing::DoAll(
        testing::SetArgPointee<1>( *rcvBuffer ),
        testing::Return( strlen( rcvBuffer ) ) ) );

EDIT:

This is the approach I've used in my projects to mock returning a char array through a pointer used as argument. First, you need to create a custom action that will copy the contents of the buffer (you cannot use SetArrayArgument in this case):

ACTION_TEMPLATE(SetArgNPointeeTo, HAS_1_TEMPLATE_PARAMS(unsigned, uIndex), AND_2_VALUE_PARAMS(pData, uiDataSize))
{
    std::memcpy(std::get<uIndex>(args), pData, uiDataSize);
}

Then, in a test use it like this:

Mock_SocketAdaptor *adaptor = new Mock_SocketAdaptor;
char rcvBuffer[] = "testingRcvWorks";
size_t bufferSize = sizeof("testingRcvWorks");

EXPECT_CALL( *adaptor, recv( testing::_, testing::_, testing::_, testing::_ ) )
    .WillRepeatedly( testing::DoAll(
        SetArgNPointeeTo<0>(std::begin(rcvBuffer), bufferSize),
        testing::Return( strlen( rcvBuffer ) ) ) );
like image 154
Marko Popovic Avatar answered Oct 14 '22 01:10

Marko Popovic