1
  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.

I want to execute a death case successfully through exit(1) but GMock says that "failed to die".

Why?

gtest.cpp

TEST(MyTest, SocketConnectionFail)
{
    MockMyTCPAPI obj_myTCP;

    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.

GMOCK WARNING:
Uninteresting mock function call - returning default value.
    Function call: socket(1, 0, 0)
          Returns: 0
Stack trace:
/home/anisha/Documents/office/tdd/tcp/server/gtest.cpp:56: Failure
Death test: obj_server.InitializeSocket()
    Result: failed to die.
 Error msg:
[  DEATH   ] 
[  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
273K
  • 29,503
  • 10
  • 41
  • 64
Aquarius_Girl
  • 21,790
  • 65
  • 230
  • 411
  • where is ret_val_socket declared and initialized? I assume it's a member variable in `Server`? If I bet that it's either uninitialized, or initialized to 0, would I be right? Make sure it's initialized to -1 so that the first `if (ret_val_socket == -1)` in `Server::InitializeSocket` is entered. – Charlie Mar 27 '19 at 20:59
  • @Charlie Thanks. The problem has been solved by the answer given below. `ret_val_socket` has -1 by default in the constructor of server.cpp. – Aquarius_Girl Mar 28 '19 at 07:12

1 Answers1

1

The output explains the issue:

GMOCK WARNING:
Uninteresting mock function call - returning default value.
    Function call: socket(1, 0, 0)
          Returns: 0

Which means myTCPAPI->socket(PF_INET, SOCK_STREAM, 0) returns 0, not -1.

Since MockMyTCPAPI obj_myTCP is a mock object (not MyTCPAPI), it won't run MyTCPAPI::socket(). You need to specify its return value. Something like the following should help:

EXPECT_CALL(obj_myTCP, socket(_, _, _))
  .WillRepeatedly(Return(-1));

Or use MyTCPAPI instead of MockMyTCPAPI in your test.

Yang
  • 7,712
  • 9
  • 48
  • 65
  • So, you mean to say that `MyTCPAPI` is not in the picture at all? I did specify Return -1 now and it being killed. – Aquarius_Girl Mar 28 '19 at 06:50
  • and `ret_val_socket` is defined in the constructor of server.cpp as -1. – Aquarius_Girl Mar 28 '19 at 06:51
  • No, MyTCPAPI is not used unless you change `MockMyTCPAPI` to `MyTCPAPI`. – Yang Mar 28 '19 at 06:51
  • By "being killed" you mean it works as expected now? – Yang Mar 28 '19 at 06:57
  • Yes, it should be killed and is being killed as the output says. BTW, I hope using MockMyTCPAPI instead of MyTCPAPI is the correct way of working with GMocks, is it? – Aquarius_Girl Mar 28 '19 at 06:59
  • 1
    Yes. Depending on your needs, you may sometimes also need fake or stubs. This QA has more information: https://stackoverflow.com/questions/346372/whats-the-difference-between-faking-mocking-and-stubbing. – Yang Mar 28 '19 at 07:02
  • There is another problem with this code which i will post in a new thread. May i post the link here so that you can take a look? – Aquarius_Girl Mar 28 '19 at 07:03
  • I can take a look tomorrow. – Yang Mar 28 '19 at 07:04
  • Also if you're writing a unit test for MyTCPAPI, you should use MyTCPAPI. – Yang Mar 28 '19 at 07:05
  • Well, my code depends upon Linux Sockets therefore I created a dummy MyTCPAPI and created a mock for MyTCPAPI . Is this a wrong approach? – Aquarius_Girl Mar 28 '19 at 07:11
  • Sounds good to me. FYI, an alternative approach is to define a `FakeTCPAPI` which always returns -1 and use `FakeTCPAPI` in your test, similar to what you have for `MyTCPAPI`. Both approaches would work. – Yang Mar 28 '19 at 07:13
  • I understand. Please tell which is the "proper" way out of those two to do it according to GMock. – Aquarius_Girl Mar 28 '19 at 07:14
  • It depends what you need. For example, would you need another test for the successful path which you'd like the `socket()` to return 0? I guess so, and then I would prefer a mock object. – Yang Mar 28 '19 at 07:18
  • https://stackoverflow.com/questions/55392339/gmock-death-case-mock-function-not-being-called – Aquarius_Girl Mar 28 '19 at 07:38