Qtestlib: QNetworkRequest не выполняется

Я хотел бы протестировать асинхронный запрос к веб-серверу. Для этой цели я создаю простой модульный тест, чтобы быстро проверить несколько строк кода:

void AsynchronousCall::testGet()
{
    QNetworkAccessManager *nam =  new QNetworkAccessManager(this);

    QUrl url("http://myownhttpserver.org");
    QNetworkRequest req(url);


    this->connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(reqFinished(QNetworkReply *)));
    QNetworkReply *rep = nam->get(req);

}

void AsynchronousCall::reqFinished(QNetworkReply *rep)
{
    qDebug() << rep->readAll();
    qDebug() << "finshed";
}

Проблема в том, что reqFinished() никогда не достигается. Если бы у меня был простой QEventLoop и loop.exec() сразу после nam->get(req); запрос выполняется.

Любой намек? Должен ли я использовать loop.exec() в каждом моем модульном тесте?


person dzen    schedule 13.04.2010    source источник


Ответы (1)


Если вы хотите протестировать асинхронное поведение, вы должны использовать QEventLoop или другой класс с аналогичной функциональностью. Я предлагаю вам написать вспомогательный метод следующим образом:

bool waitForSignal(QObject *sender, const char *signal, int timeout = 1000) {
    QEventLoop loop;
    QTimer timer;
    timer.setInterval(timeout);
    timer.setSingleShot(true);

    loop.connect(sender, signal, SLOT(quit()));
    loop.connect(&timer, SIGNAL(timeout()), SLOT(quit()));
    timer.start();
    loop.exec();

    return timer.isActive();
}

Затем вы можете использовать его в своих модульных тестах следующим образом:

void AsynchronousCall::testGet()
{
    QNetworkAccessManager *nam =  new QNetworkAccessManager(this);

    QUrl url("http://myownhttpserver.org");
    QNetworkRequest req(url);


    this->connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(reqFinished(QNetworkReply *)));
    QNetworkReply *rep = nam->get(req);
    QVERIFY(waitForSignal(nam, SIGNAL(finished(QNetworkReply*)), 5000));
}

Есть и другие проблемы с вашим тестом:

  1. Тесты, которые зависят от сетевого подключения, не должны быть модульными тестами. Вы хотите, чтобы ваши модульные тесты работали молниеносно, чего невозможно добиться при сетевых подключениях.
  2. Ваш тест на самом деле ничего не проверяет: он просто помещает некоторую информацию в консоль отладки. Вы должны определить ожидания и проверить их, используя макросы QVERIFY и QCOMPARE.
  3. QTest отстой ИМХО. Если вы создаете тестовую базу с нуля, начните использовать gtest + gmock.
person chalup    schedule 13.04.2010
comment
Модульные тесты хороши для тестирования сетевых сервисов, хотя спорно, является ли QTest способом протестировать что-то внешнее, это путь... - person Smar; 05.04.2011
comment
Оказывается, в KDE есть функция QTest::kWaitForSignal, которая делает то же самое. - person Vishesh Handa; 15.03.2012