QSignalSpy等待和两个信号

问题描述:

我想在基于Qt的项目(Qt 5,C++ 03)中编写一个类的单元测试。QSignalSpy等待和两个信号

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来代替吗?

+0

如果你不带参数调用spy.wait(),它会r一旦信号在5000ms内发射,就立即生效。你不需要等待5000ms。 – Kahn

解决方案与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); 
+0

如果发出'suceeded()'和'failed()'的代码已经取决于Qt的事件循环,我认为这不会起作用。你不使用Qt的事件循环吗? – Mitch

您可能会需要使用一个循环,并手动调用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);