Протестируйте асинхронный вызов с помощью тестов Google

#c #asynchronous #googletest

#c #асинхронный #googletest

Вопрос:

У меня есть коммуникатор классов, который проверяет, может ли он подключить тестовый сервер. Вот как я это называю:

 class CommunicatorTest
{
public:
    CommunicatorTest() {}
    bool doTest()
    {
        bool _success;
        Parameters params;
        Communicator communicator;
        communicator.connect(params, [this, amp;_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);
}
  

Я пытался использовать условие и мьютекс, чтобы сделать этот код синхронным, но это не удается, в журналах говорится только, что тест был запущен и немедленно завершен.

Есть ли способ проверить переменную успеха из обратного вызова с помощью тестов Google? Заранее спасибо.

Ответ №1:

В этих случаях лучшим решением является создание макета, который эмулирует поведение сервера. Вы не должны полагаться (за исключением случаев крайней необходимости) на внешние состояния при запуске своих тестов.

Тесты могут завершиться неудачей, поскольку сервер не подключен, нет подключения к Интернету или любого другого состояния.

Вы можете использовать что-то вроде Google Mock, который теперь является частью набора тестов Google, для эмуляции поведения:

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

Затем сделайте что-то вроде этого:

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

  EXPECT_TRUE(server.isConnected());
}     
  

Вы можете имитировать обработку ошибок:

 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
}     
  

Комментарии:

1. Спасибо, очень хорошее объяснение.

Ответ №2:

Как человек, который пишет асинхронный код, я много раз сталкивался с этой проблемой — кажется, что большинство существующих тестовых фреймворков C / C не имеют реальной поддержки для тестирования асинхронного кода. В основном необходим цикл событий, в котором вы можете планировать выполнение действий (имитировать временные внешние события и т.д.), А также механизм для регистрации ответов и, при необходимости, проверки порядка, в котором они происходят. Итак, вместо того, чтобы пытаться как-то адаптировать существующую структуру (что, вероятно, привело бы к большим усилиям), я создал свою собственную. Я использовал его для тестирования разработанного мной класса promise, подобного javascript, и он хорошо справился со своей задачей. Если вам интересно, я только что опубликовал его на GitHub:https://github.com/alxvasilev/async-test