Qtestlib: QNetworkRequest не выполнен - PullRequest
2 голосов
/ 13 апреля 2010

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

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 () в каждом моем тесте?

1 Ответ

13 голосов
/ 13 апреля 2010

Если вы хотите проверить асинхронное поведение, вы должны использовать 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 .
...