2014-03-13 127 views
3

我試圖測試一個基於QObject的基於類將emit信號異步(實際上從後臺線程)。谷歌測試/模擬與Qt信號

我看到一個帖子在這裏這樣做的:

https://groups.google.com/forum/#!topic/googlemock/RTgynKPa6ew

哪個鏈接到這個源代碼:

http://www.etotheipiplusone.com/projects/qsignalmock/qsignalmock.cpp http://www.etotheipiplusone.com/projects/qsignalmock/qsignalmock.h

這似乎是我想要的東西 - 但是作爲作者提到這缺少超時/同步步驟。

由於鏈接帖子相當老,我想知道是否有更好/更現代的方式來處理這個問題?我不能相信我是唯一一個想驗證一個班級在預計的時間範圍內發出預期數據的人。

例如讓我們說我們有啓動一個線程,睡覺,然後發出信號的對象:

class ASyncObj : public QObject 
{ 
public: 
    void begin(); // fires OnResult after ~10 seconds using QTimer or QThread for example 
signals: 
    void OnResult(bool wasError); 
}; 

TEST_F(ASyncTest, DidSignalFire) 
{ 
    ASyncObj testObj; 
    testObj.begin(); 

    // How can I wait for a timeout and verify that OnResult was called with a value of false? 
} 

編輯:

在我使用QSignalSpy但發現它到底有一個問題,它檢測發射的信號取決於它是同步還是異步。所以,我想出了這個:

class QSignalSpyEx : public QSignalSpy 
{ 
public: 
    QSignalSpyEx(const QObject* obj, const char* aSignal) 
     : QSignalSpy(obj, aSignal) 
    { 

    } 

    bool waitForSignal(int timeout = 5000000) 
    { 
     // if true then signal was emitted synchronously 
     bool result = count() > 0; 
     if (!result) 
     { 
      // if false then wait for async emit 
      result = wait(timeout); 
     } 
     return result; 
    } 
}; 

這使我原來的例子變成:

TEST_F(ASyncTest, DidSignalFire) 
{ 
    ASyncObj testObj; 

    QSignalSpyEx spy(&testObj, SIGNAL(OnResult(bool))); 

    testObj.begin(); 

    spy.waitForSignal(); // assert true 
    spy.takeFirst().at(0).toBool(); // assert whatever you expected the result to be 

} 

回答

1

我不知道你爲什麼不使用QtTestLib(這是很方便)。無論如何,這包含允許測試信號的QSignalSpy
您應該調用wait(int)方法,該方法啓動事件循環直到信號到達或發生超時。

我很肯定你可以將它與googletest混合使用。

+0

看起來像這樣行不通,因爲wait(int)有競態條件。如果在等待被調用之前發出信號,那麼看起來好像信號永遠不會被髮射,是否有解決此問題的方法? – paulm

+1

不會有比賽條件! 1.在開始實際測試之前(在調用開始之前),您應該創建'QSignalSpy',然後在調用'begin'之後調用'wait',2.默認情況下,由不同線程發出的信號所調用的時隙由目標事件循環線。 –

+0

我確實存在競爭條件,因爲它取決於信號是異步發射還是同步發射。如果同步然後信號間諜等待將認爲沒有信號被髮射,否則它會。儘管我設法創建了一個包裝來解決這個問題。 – paulm