2008-12-19 67 views
1

我是單元測試新手,目前在找到一種體面的方法來測試包含分支的方法時遇到了問題。包含條件條件的單元測試方法的最佳實踐

我創建了一個小的演示方法,我希望可以用來解釋這個問題。

public void ExportAccounts() 
{ 
    int emptyAccounts = 0; 
    int nonEmptyAccounts = 0; 
    int errorous = 0; 
    string outputPath = this.GetOutputPath(); 
    Account[] accounts = this.MyWebserviceAdapter.GetAccounts(); 
    foreach(Account account in accounts) 
    { 
     try 
     { 
      if(account.Amount > 0) 
      { 
       this.ExportNonEmpty(outputPath, account); 
       nonEmptyAccounts++; 
      } else { 
       this.ExportEmptyAccount(outputPath, account); 
       emptyAccounts++; 
      } 
     } catch(Exception e) { 
      logger.error(e); 
      errorous++; 
     } 
    } 
    logger.debug(string.Format("{0} empty/{1} non empty/{2} errorous", emptyAccounts, nonEmptyAccounts, errorous)); 
} 

我可以模擬MyWebserviceAdapter以返回預定義的帳戶列表。我是否應該在同一個測試中輸入空的和非空的賬戶清單,還是應該單獨進行測試?

另外我的ExportNonEmpty()和ExportEmpty()方法是私有的,但是將文件寫入文件系統。我應該提供一個模擬FileProvider,以便文件系統不被觸及?

我應該公開ExportNonEmpty()和ExportEmpty()以便能夠分別測試這些嗎?這些方法還包含一些if-then-else語句,並可以引發異常和異常。

我發現如果我爲每個代碼路徑創建一個測試我有從一個測試複製代碼到另一個 - 生成嘲笑等..不是有點奇怪?

我應該公開計數器變量作爲出變量,以便能夠在調用方法後驗證它們嗎?

this.GetOUtputPath()通過靜態的ConfigurationManager從配置文件中獲取值。我應該a)通過爲testt下的類創建一個部分模擬並覆蓋GetOutputPath方法或者b)創建我自己的可以被嘲笑的配置適配器來模擬這一點?

我正在使用nunit和Rhino Mocks。

回答

1

我會用幾個測試向量來測試它:全空,全非空,以及以空和非空開始和結束的混合開始和結束。

至於驗證結果:揭露和測試計數器會給出一個「白盒」測試,在測試中知道對象的內部狀態,這會給出一個更徹底的測試,但是使其更難稍後更改實施。 (如果更改實現,即使效果相同,測試也可能失敗)。

我的偏好通常是測試«黑匣子»,只測試操作的外部可觀察到的後果。然後,如果公開的功能仍然相同,則可以更改內部結構和迴歸測試。但是,這可能需要更多的模擬編碼。

對於java,有相當多的庫可以幫助您構建模擬對象,我不知道.net,但我會假設情況相同。

+0

那麼你會爲每個測試向量有一個單獨的測試方法嗎?這樣做會導致許多嘲笑必須複製到我所推測的每種測試方法中。你可以評論你將如何做到這一點? – Fadeproof 2008-12-19 13:36:06

1

針對每種情況的單獨測試。我假設你相信foreach遍歷一個包含兩者的循環。我會。假設你正在測試你在其他地方嘲笑的方法,以確保它在出現時正確地返回兩種類型的帳戶。

除了複製代碼之外,還可以通過將常用代碼提取到測試類中的方法甚至TestHelper類中來重構代碼。如果需要使它們參數化,使它們通常可用。

您應該可以通過爲測試中的類添加訪問器來測試您的私有方法。如果在私有方法中使用「創建單元測試」右鍵單擊菜單項,或者將私有方法作爲一個單獨添加以創建單元測試以添加整個課程,則會自動添加一個。爲了測試ExportAccounts,只需使用您知道的數據,並且不會拋出異常,以便您可以測試直線邏輯和異常處理。

我不會公開方法變量。在方法之外不需要它們。然而,你應該模擬記錄器以確保它被調用期望的參數。

創建ConfigurationAdapter(或Wrapper)並將其注入到類中以除去對靜態類的依賴關係。嘲笑適配器或提供一個假實現,您的選擇。無論如何,去除依賴是一種很好的模式。我不喜歡在測試中嘲笑或殘缺任何東西。

編輯:有關單位測試基本的閱讀,我會建議Pragmatic Unit Testing(C#版本)和Code Complete單元測試的章節。你可能也想拿起Test Driven Development in .Net,但其他人更一般。

+0

您提到提取通用代碼,我同意這將是一個好主意 - 但問題是您注入的模擬不能提取,因爲我在每個測試方法中設置預期的調用,因此如果測試不同條件採用不同的測試方法。 – Fadeproof 2008-12-19 13:51:47