Qtestlib: QNetworkRequest non exécuté
-
26-09-2019 - |
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?
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:
- 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.
- 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.
- 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