使用带有QNetworkAccessManager的Google Test永远不会完成

时间:2014-07-28 16:28:08

标签: qt qt5 signals-slots googletest qnetworkaccessmanager

我正在尝试创建一个使用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-&gt; show();然后我必须手动关闭窗口小部件并完成测试。但是,这对自动化单元测试并不是非常有用。

如果我使用上面的while循环来等待_data设置为某个东西,那么QNetworkAccessManager就不会发生任何事情,它会永远循环。

在任何事情向前推进之前是否需要进行一些调用?为什么 - &gt; show()&#39;工作?&#39;

1 个答案:

答案 0 :(得分: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();
};