Question

Je voudrais tester une requête asynchrone à un serveur Web. A cette fin, je crée simple unittest pour essayer rapidement quelques lignes de code:

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";
}

Le problème est que reqFinished () est jamais atteint. Si je devais simple et QEventLoop et un loop.exec () juste après la nam-> get (REQ); la demande est exécutée.

Tout soupçon? Dois-je utiliser un loop.exec () dans tous mes unittests?

Était-ce utile?

La solution

Si vous voulez tester le comportement asynchrone, vous devez utiliser QEventLoop ou une autre classe avec des fonctionnalités similaires. Je vous suggère d'écrire méthode d'aide comme ceci:

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();
}

Ensuite, vous pouvez l'utiliser dans vos tests unitaires comme ceci:

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));
}

Il y a aussi d'autres problèmes avec votre test:

  1. Les tests qui dépendent de la connexion réseau ne doit pas être des tests unitaires. Vous voulez que vos tests unitaires à ultra-rapide, ce qui est impossible à réaliser avec des connexions réseau.
  2. Votre test n'a pas vraiment rien de test: il met juste quelques informations à la console de débogage. Vous devez définir les attentes et les vérifier en utilisant des macros QVERIFY et QCOMPARE.
  3. QTest suce mon humble avis. Si vous créez base de test à partir de zéro, commencez à utiliser gtest + gmock à la place
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top