문제

I would like to test an asynchronous request to a webserver. For that purpose I'm creating a simple unittest to quickly try a few lines of 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";
}

The problem is that reqFinished() is never reached. If I had a simple QEventLoop and and a loop.exec() just after the nam->get(req); the request is executed.

Any hint ? Do I have to use a loop.exec() in my every unittests ?

도움이 되었습니까?

해결책

If you want to test asynchronous behavior, you have to use QEventLoop or other class with similar functionality. I suggest you write helper method like this:

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

Then you can use it in your unit tests like this:

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

There are also other issues with your test:

  1. Tests that depend on network connection shouldn't be unit tests. You want your unit tests to be blazing fast, which is impossible to achieve with network connections.
  2. Your test doesn't really test anything: it just puts some info to debug console. You should define expectations and verify them using QVERIFY and QCOMPARE macros.
  3. QTest sucks IMHO. If you're creating test base from scratch, start using gtest + gmock instead.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top