Использование Google Test с QNetworkAccessManager никогда не выдает finished


Я пытаюсь создать тест, который будет использовать QNetworkAccessManager для общения с нашим RESTful api. Все, что я хочу сделать, это захватить простой объект JSon с помощью QNetworkAccessManager. Мой код выглядит так:

Connection::Connection(QString const &username, QString const &password, QString const &url, QString const &api) : 
    _user(username), _pass(password), _url(url) {

    _manager = new QNetworkAccessManager(this);
    QObject::connect(_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(receiveReply(QNetworkReply*)));

    QNetworkRequest request;
    request.setUrl(QUrl(_url.append(api)));
    request.setRawHeader("Authorization", QString("Basic ").append(QString("%1:%2").arg(_user).arg(_pass)).toUtf8());
    request.setHeader(QNetworkRequest::ContentTypeHeader, "text/json");

    QNetworkReply *reply = _manager->get(request);
}
void Connection::Connection(QNetworkReply *reply) {
    //do some validation of the reply...
    _data = QJsonDocument::fromJson(reply->readAll());
}
QJsonDocument Connection::data() const {
    return _data;
}

...

#include <gtest/gtest.h>
#include "Connection.h"
#include <QApplication>
TEST(ConnectionTest, creation) {
    int argc = 0;
    char *argv = 0;
    QApplication a(argc, &argv);
    Connection *connect = new Connection("user","abc123", https://mytest.com/", "api/");
    connect->deleteLater();
    while (connect->data().isEmpty()) {
        //loop forever
    }
}

Первоначально я тестировал, имея соединение также быть QWidget. Готовый сигнал будет отображаться только в том случае, если я вызову connection->show(); затем я должен закрыть виджет вручную, и тест завершится. Однако это не очень полезно для автоматизированного модульного тестирования.

Если я использую описанный выше цикл while, чтобы дождаться, пока _data не будет установлена на что-то, то с QNetworkAccessManager никогда ничего не происходит, и он петляет вечно.

Есть ли какой-то вызов, который должен произойти, прежде чем что-то сдвинется с места? Почему - > show() 'работает?'
1 3

1 ответ:

Вы не вращаете цикл событий, поэтому не ожидайте, что что-то асинхронное будет работать вообще.

Вам нужно добавить сигнал к классу Connection, который указывает, когда это сделано, и использовать этот сигнал, чтобы выйти из цикла событий:

TEST(ConnectionTest, creation) {
    int argc = 0;
    char *argv = 0;
    QCoreApplication app(argc, &argv);
    // No need to allocate the connection on the heap!
    Connection connection("user", "abc123", "https://mytest.com/", "api/");
    QObject::connect(&connection, &Connection::finished, 
                     &app, &QCoreApplication::quit());
    app.exec();
}

Можно добавить экземпляр QApplication в качестве члена класса ConnectionTest.

Также нет необходимости удваивать количество выделений кучи, имея член QNetworkAccessManager * manager. Вы можете иметь его в качестве постоянного члена:

class Connection : public QObject {
  Q_OBJECT
  QNetworkAccessManager manager;
  Q_SLOT void receiveReply(QNetworkReply *) { 
    ...
    emit finished();
  }
public:
  explicit
  Connection(const QString & user, const QString & password,
             const QUrl & url, const QString & path, 
             QObject * parent = 0) : QObject(parent) { ... }
  Q_SIGNAL void finished();
};