2015-11-05 244 views
4

我想在基於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

回答

1

解決方案與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

4

您可能會需要使用一個循環,並手動調用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);