使用Google Test和QNetworkAccessManager时永远不会发出finished信号

3

我正在尝试创建一个测试,使用QNetworkAccessManager与我们的RESTful API通信。我想做的就是使用QNetworkAccessManager获取一个简单的JSON对象。我的代码如下:

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

最初,我尝试将Connection作为QWidget进行测试。只有当我调用connection->show()时,finished信号才会显示。然后,我必须手动关闭小部件,测试才能完成。然而,这对于自动化单元测试并不是很有用。

如果我使用上述while循环等待_data被设置为某些内容,则QNetworkAccessManager永远不会发生任何事情,并且它会一直循环下去。

是否需要在向前移动之前进行某些调用?为什么-show()“有效”?

1个回答

4

如果您不旋转事件循环,那么不要期望任何异步操作都能正常工作。

您需要向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();
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接