2013-02-14 79 views
2

我有單元測試調用ApplicationShouldBeInstalled(app)以確保它正常工作。下面的實際生產代碼也會調用該方法,所以它不會無意中安裝應用程序。但是,沒有任何東西阻止開發人員在檢查完成後刪除該行代碼。而且我的單元測試無法捕捉到,因爲測試正在測試ApplicationShouldBeInstalled(app)方法,而不是InstallApplications()方法。移動方法嘲笑?

我不能從我的測試代碼中調用InstallApplications(),因爲它會嘗試安裝應用程序。 InstallApplication(app)是同一個類中的一個方法,而不是另一個類,我可以用它來模擬它。有沒有辦法確保InstallApplications()始終執行該檢查?我想我可以將ApplicationShouldBeInstalled(app)移動到另一個類並嘲笑它,但是我只是爲了測試/嘲弄而移動代碼。有沒有更好的辦法?

public void InstallApplications() 
{ 
    foreach (App app in this._apps) 
    { 
     if (!ApplicationShouldBeInstalled(app)) { continue; } 

     InstallApplication(app); 
    }      
} 

模擬選項看起來像這樣。在運行時,Container會返回真正的實現,並且在運行測試時會返回一個模擬。

public void InstallApplications() 
{ 
    foreach (App app in this._apps) 
    { 
     if (!ApplicationShouldBeInstalled(app)) { continue; } 

     Container.Resolve<IInstaller>().InstallApplication(app); 
    }      
} 
+1

你可以從方法提取一個接口,然後模擬接口? – Robert 2013-02-14 19:52:56

+0

欲瞭解更多信息,請參閱http://msdn.microsoft.com/en-us/library/fb3dyx26.aspx – 2013-02-14 19:54:04

+0

如果我的理解正確,那是我在我的問題中列出的選項。所以,是的,我可以,但我想知道是否有更好的方法。國際海事組織,所有這些代碼都屬於它目前所在的班級。我會移動它,如果這是我必須做的才能夠測試它。 – 2013-02-14 19:54:22

回答

2

是的,刪除控制是否應該從處理安裝的代碼安裝應用程序的策略的代碼。這將允許您單獨測試這兩部分代碼,並確信每個代碼都在按照您的要求進行操作。我甚至會在這裏有3個合作者。控制循環的代碼,控制對策略驗證的代碼,以及執行安裝的代碼。三件,可獨立測試,更容易驗證。

foreach (var app in this._apps) 
{ 
    if (!applicationInstallationPolicyProvider.CanInstall(app)) // can be mocked away 
    { 
      continue; 
    } 

    applicationInstaller.Install(app); // can also be mocked away 
} 

我認爲你的關鍵是當你在問題中說「你不能在測試中運行安裝代碼」。但是,對於您確認實際上將在需要時調用安裝代碼應該很重要。這應該是足夠的動機已經試圖孤立它,不管你是否採取我可能喜歡的程度。

+0

這符合我剛剛添加到我的問題,所以我相信我是在正確的道路上。謝謝! – 2013-02-14 20:01:55

+2

我認爲你的關鍵是當你在問題中說「你不能在測試中運行安裝代碼」。但是,驗證循環實際將*調用安裝代碼對你來說應該很重要。已經有足夠的動機來嘗試隔離它。 – 2013-02-14 20:04:43

+0

同意!現在就做。謝謝! – 2013-02-14 20:13:45

1

當你將它提取到一個接口時,你並不真正刪除屬於該類的代碼。您正在要求班級實施成員。使用接口的一個主要好處是它允許你嘲笑它們,所以你不會真正改變功能。你嘲笑界面,然後你確認一個特定的方法實際上正在做你期望的操作。

在旁邊注意它也允許您使用依賴注入,以便您不在內存中不斷創建對象的實例。

+0

同意。謝謝。 – 2013-02-14 20:02:34