Aquarius_Girl
Aquarius_Girl

Reputation: 22916

GMock death case - mock function not being called

  1. I have created a mock of an external socket api in my_inet.cpp file.
  2. GMock functions for that socket api is in mock.h file.
  3. I am using my created socket api of my_inet in server.cpp file.
  4. The test is written in gtest.cpp.

The death case that is written here is executing as per the output. Output says that the the process died. But it also says that the socket() call was never made so the case is shown as failed.

Please tell what is the reason for this and what is the solution.

gtest.cpp

TEST(MyTest, SocketConnectionFail)
{
    MockMyTCPAPI obj_myTCP;

    EXPECT_CALL( obj_myTCP, socket( 1, 0, 0 ))
    .Times( 1 )
    .WillOnce( Return( -1 ));

    Server obj_server( &obj_myTCP );

    EXPECT_DEATH( obj_server.InitializeSocket(), "No socket connection!");
}

server.cpp

int Server::InitializeSocket()
{
  if( ret_val_socket == -1 )
  {
        ret_val_socket = myTCPAPI->socket( PF_INET, SOCK_STREAM, 0 );

        if( ret_val_socket == -1 )
        {
            printf( "\nNo socket connection!" );
            exit(1);
        }
        return ret_val_socket;
  }
  else
  {
        printf( "Warning! Attempting to create socket again. %d" , ret_val_socket);
        return 2;
  }

  return 0;
}

my_inet.cpp

int MyTCPAPI::socket( int arg1, int arg2, int arg3 )
{
        return -1;
}

Output:

[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from MyTest
[ RUN      ] MyTest.SocketConnectionFail

[WARNING] /usr/src/gtest/src/gtest-death-test.cc:825:: Death tests use fork(), which is unsafe particularly in a threaded context. For this test, Google Test couldn't detect the number of threads.

No socket connection!
/home/../Documents/office/tdd/tcp/server/gtest.cpp:49: ERROR: this mock object (used in test MyTest.SocketConnectionFail) should be deleted but never is. Its address is @0x7fff2e94a890.
ERROR: 1 leaked mock object found at program exit.
/home/../Documents/office/tdd/tcp/server/gtest.cpp:56: Failure
Death test: obj_server.InitializeSocket()
    Result: died but not with expected error.
  Expected: No socket connection!
Actual msg:
[  DEATH   ] 
/home/../Documents/office/tdd/tcp/server/gtest.cpp:49: Failure
Actual function call count doesn't match EXPECT_CALL(obj_myTCP, socket( 1, 0, 0 ))...
         Expected: to be called once
           Actual: never called - unsatisfied and active
[  FAILED  ] MyTest.SocketConnectionFail (3 ms)
[----------] 1 test from MyTest (3 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (3 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] MyTest.SocketConnectionFail

 1 FAILED TEST

Upvotes: 3

Views: 1353

Answers (1)

Mike van Dyke
Mike van Dyke

Reputation: 2868

According to the docs, EXPECT_DEATH and ASSERT_DEATH spawn a child process which executes the death test statement (in this case obj_server.InitializeSocket()).

After termination of the child process, they check the exit code and the stderr message. If the exit code is 0 or the message in stderr does not match the expected value, the test is invalid. stdout on the other hand is not checked.

Therefore, printf( "\nNo socket connection!" ) has to be replaced with fprintf(stderr, "\nNo socket connection!" ) right before the applicatons exits:

int Server::InitializeSocket()
{
  if( ret_val_socket == -1 )
  {
        ret_val_socket = myTCPAPI->socket( PF_INET, SOCK_STREAM, 0 );

        if( ret_val_socket == -1 )
        {
            fprintf(stderr, "\nNo socket connection!" ); // print to stderr here
            exit(1);
        }
        return ret_val_socket;
  }
  else
  {
        printf( "Warning! Attempting to create socket again. %d" , ret_val_socket);
        return 2;
  }

  return 0;
}

As pointed out in the comments, EXPECT_CALL will fail. Using AnyNumber when specifying the number of times it might be called could help in this case (only the first call will then return -1 and the test case might still fail).

TEST(MyTest, SocketConnectionFail) { MockMyTCPAPI obj_myTCP;

EXPECT_CALL( obj_myTCP, socket( 1, 0, 0 ))
.Times(testing::AnyNumber())
.WillOnce( Return( -1 ));

Server obj_server( &obj_myTCP );

EXPECT_DEATH( obj_server.InitializeSocket(), "No socket connection!");

}

Upvotes: 4

Related Questions