我正在尝试创建一个使用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;
答案 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();
};