【问题标题】:QSignalSpy wait and two signalsQSignalSpy 等待和两个信号
【发布时间】:2015-11-05 07:26:36
【问题描述】:

我正在尝试为基于 Qt 的项目(Qt 5、C++03)中的类编写单元测试。

class Transaction { // This is just a sample class
//..
public signals:
   void succeeded();
   void failed();
}

Transaction* transaction = new Transaction(this);
QSignalSpy spy(transaction, SIGNAL(succeeded()));
transaction->run();
spy.wait(5000); // wait for 5 seconds

我希望我的测试运行得更快。 在发出信号failed() 后如何中断wait() 调用,以防事务失败?

我在 QSignalSpy 类中看不到任何可用的插槽。

我应该改用 QEventLoop 吗?

【问题讨论】:

  • 如果你在没有参数的情况下调用 spy.wait(),它会在 5000 毫秒内发出信号后立即返回 true。您无需等待 5000 毫秒。

标签: c++ qt unit-testing qt5 signals-slots


【解决方案1】:

您可能必须使用循环并手动调用QTest::qWait(),而这两个信号都没有发出:

QSignalSpy succeededSpy(transaction, SIGNAL(succeeded()));
QSignalSpy failedSpy(transaction, SIGNAL(failed()));
for (int waitDelay = 5000; waitDelay > 0 && succeededSpy.count() == 0 && failedSpy.count() == 0; waitDelay -= 100) {
    QTest::qWait(100);
}

QCOMPARE(succeededSpy.count(), 1);

【讨论】:

    【解决方案2】:

    QTestEventLoop 的解决方案:

    QTestEventLoop loop;
    QObject::connect(transaction, SIGNAL(succeeded()), &loop, SLOT(exitLoop()));
    QObject::connect(transaction, SIGNAL(failed()), &loop, SLOT(exitLoop()));
    transaction->run();
    loop.enterLoopMSecs(3000);
    

    使用计时器和QEventLoop的解决方案:

    Transaction* transaction = new Transaction(this);
    QSignalSpy spy(transaction, SIGNAL(succeeded()));  
    QEventLoop loop;  
    QTimer timer;
    QObject::connect(transaction, SIGNAL(succeeded()), &loop, SLOT(quit()));
    QObject::connect(transaction, SIGNAL(failed()), &loop, SLOT(quit()));
    QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
    timer.start(3000);
    loop.exec();
    transaction->run();
    QCOMPARE(spy.count(), 1);
    

    【讨论】:

    • 如果发出 suceeded()failed() 的代码已经依赖于 Qt 的事件循环,我认为这不会起作用。你不使用Qt的事件循环吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多