Search code examples
c++asynchronousgoogletest

Test asynchronous call via google tests


I have a class Communicator that tests whether it can connect the test server. Here is how I call it:

class CommunicatorTest
{
public:
    CommunicatorTest() {}
    bool doTest()
    {
        bool _success;
        Parameters params;
        Communicator communicator;
        communicator.connect(params, [this, &_success](bool success)
        {
            statusCode = errorCode;
            m_condition.notify_one();
        });

        std::unique_lock<std::mutex> uGuard(m_mutex);
        m_condition.wait(uGuard);
        return _success;
    }

private:
    std::mutex m_mutex;
    std::condition_variable m_condition;
};

bool communicatorTest()
{
    CommunicatorTest test;
    bool success = test.doTest();
    return success;
}

TEST(CommunicatorTest, test_eq)
{
    EXPECT_EQ(communicatorTest(), true);
}

I tried to use condition and mutex to make this code synchronous but it fails, the logs say only that test was running and immediately finishes.

Is there a way to test success variable from the callback using google tests? Thanks in advance.


Solution

  • In those cases the best solution is to create a mock that emulates the behavior of the server. You should not rely (unless extremely necessary) in external states when running your tests.

    The tests may fail because the server is not connected, there is no internet connection or whatever condition.

    You can use something like Google Mock, now part of Google Test suite to emulate the behavior:

    class MockServer : public Server  {
     public:
      MOCK_METHOD2(DoConnect, bool());
      ....
    };
    

    Then do something like this:

    TEST(ServerTest, CanConnect) {
      MockServer s;                          
      EXPECT_CALL(s, DoConnect())              
          ..WillOnce(Return(true));
    
      EXPECT_TRUE(server.isConnected());
    }     
    

    You can simulate the error handling:

    TEST(ServerTest, CannotConnect) {
      MockServer s;                          
      EXPECT_CALL(s, DoConnect())              
          ..WillOnce(Return(false));
    
      EXPECT_FALSE(server.isConnected());
      // ... Check the rest of your variables or states that may be false and
      // check that the error handler is working properly
    }