2011-04-08 68 views
4

我是新來的測試和TDD,但決定嘗試和學習。目前我正在嘗試開發一個類SettingsManager來處理我的應用程序的設置。它將存儲應用程序的狀態以及關閉時間SettingsManager將使用QSettings保存狀態(並在啓動時讀取)。現在我想模擬QSettings,所以我的測試不會依賴隨機狀態。但是,我找不到任何明智的方式來模擬/保留它,因爲我需要的方法(QSettings :: value())不是虛擬的。如何存根/模擬Qt類?

也許我在做一些概念上的錯誤?或者有沒有辦法模擬這個非虛擬的方法調用?

例子:假設我有這個類:

class SettingsManager 
{  
private: 
    /* app state variables */ 
    QSettings *settings; 
    bool m_objectsVisible; 

public: 

    SettingsManager(QSettings *settings) 
    { 
     this->settings = settings; 
    } 

    void readSettings() 
    { 
     m_objectsVisible = settings.value("Settings/ObjectsVisible").toBool(); 
    } 

    bool objectsVisible() 
    { 
     return m_objectsVisible; 
    } 
}; 

我想測試這種方式(我用Hippomocks語法只是爲了讓一個想法)

void TestObjectsAreVisible() { 
    MockRepository mocks; 
    QSettings *settingsMock = mocks.ClassMock<QSettings>(); 
    mocks.ExpectCall(settingsMock , QSettings::value).With("Settings/ObjectsVisible").Return(true); 
    SettingsManager *sManager = new SettingsManager(settingsMock); 
    sManager->readSettings(); 
    assertTrue(sManager->objectsVisible); 
} 

回答

2

我想你是單位測試QSettings,但這不是單元測試的重點。

如果你想學習TDD,從簡單的事情開始。例如,嘗試創建MVP三元組類(模型和演示者應具有接口,而視圖是qt類類型)。然後完全單元測試模型和演示者。該視圖不應該有任何邏輯 - 只有qt調用。

事情是這樣的:

struct View : (some qt object) 
{ 
    View(PresenterIface &p_) : p(p_) {} 

    void buttonClicked() 
    { 
    p.buttonClicked(); 
    } 

    PresenterIface p; 
}; 

struct Presenter : PresenterIface 
{ 
Presenter(ModelIface &m_) : m(m){} 
void buttonClicked() 
{ 
    m.setValue(); 
} 

ModelIface &m; 
}; 

struct Model : ModelIface 
{ 
    void setValue() 
    { 
    // do something 
    } 
}; 
+3

借調。不要測試QSettings。測試你的課程,保存你的應用程序設置。 – Jay 2011-04-08 14:27:35

+0

我不想測試QSettings。我想從QSettings中得到不同的預定義返回值,所以我可以確定我的類中的邏輯的行爲如預期。例如,如果QSettings返回的值爲空或註冊表中沒有這樣的字段會怎麼樣?手動檢查這些條件非常耗時,所以我想知道是否有辦法模擬QSettings? – ashagi 2011-04-11 04:22:44

+1

@ashagi您可以將類型QSettings的對象傳遞給SettingsManager類型的對象,在該對象中創建對該對象的引用。然後在測試中,您可以在QSettings對象中設置各種字段,並檢查SettingsManager的方法是否返回期望值。 – 2011-04-11 08:26:30