带信号和插槽的测试方法

Test method with Signals and Slots

本文关键字:测试方法 插槽 信号      更新时间:2023-10-16

我在QT控制台应用程序中具有以下两个简单方法:

void Webservice::getFile(PostElement el)
{
  parameter = ⪙
  QUrl url(PATH);
  QUrlQuery query;
  query.addQueryItem(el.getParam(), el.getValue());
  url.setQuery(query);
  request.setUrl(url);
  manager->get(request);
  connect(manager, SIGNAL(finished(QNetworkReply*)), this,
          SLOT(downloadCompleted(QNetworkReply*)));
}
void Webservice::downloadCompleted(QNetworkReply *reply)
{
  QByteArray b = reply->readAll();
  qDebug() << "Download completed!";
  QFile file("/tmp/" + parameter->getValue());
  file.open(QIODevice::WriteOnly);
  file.write(b);
  file.close();
  reply->deleteLater();
}

我创建了一个QTest项目来测试getFile方法。

#include <QtTest>
#include <QCoreApplication>
// add necessary includes here
#include "webservice.h"
class WebserviceTest : public QObject
{
  Q_OBJECT
public:
  WebserviceTest();
  ~WebserviceTest();
private:
  Webservice ws;
private slots:
  void initTestCase();
  void cleanupTestCase();
  void getFile();
};
WebserviceTest::WebserviceTest()
{
}
WebserviceTest::~WebserviceTest()
{
}
void WebserviceTest::initTestCase()
{
}
void WebserviceTest::cleanupTestCase()
{
}
void WebserviceTest::getFile()
{
  PostElement el{"file", "myPic.png"};
  ws.getFile(el); // it should wait for the slot to be executed
}
QTEST_MAIN(WebserviceTest)
#include "tst_webservicetest.moc"
如您所见,它具有信号和插槽。如果我在原始项目上运行该一个,我会发现downloadCompleted无问题执行(因为它正在使用事件循环)。但是在测试项目中,没有调用插槽。我搜索了使用Qsignalspy的一些示例,但是目前我尚未成功执行该插槽。

如何告诉我的测试"等待"插槽完成?

这正是QSignalSpy的目的,它基本上旋转了新的QEventLoop,等待信号被执行。您的测试启动和异步操作,但它不会等待它完成,因此在操作正在进行时会破坏对象。

QT测试还具有一些内置超时,可防止使用QSignalSpy时停止的测试。在您的情况下,您需要从类Webservice发出新信号,以表明下载完成,例如(您也可以将参数传递给信号),如果需要:

class Webservice : public QObject {
     Q_OBJECT
     // Constructors etc.
     signals:
     void finished();
}

然后在void Webservice::downloadCompleted(QNetworkReply *reply)的末尾:

emit finished();

在您的测试中,类似的东西:

PostElement el{"file", "myPic.png"};
// Prepare spy
QSignalSpy spy(&ws, SIGNAL(finished));
ws.getFile(el);
// Wait for result - by default this waits 5 seconds
spy.wait();
// Check if we had a timeout or actually signal was raised
QCOMPARE(spy.count(), 1);