2008-10-21 38 views
1

在我的問題As a 「mockist」 TDD practitioner, should I mock other methods in the same class as the method under test?Avdi回答:「我個人認爲,嘲諷自我幾乎總是一個代碼的氣味。它的測試實現,而不是行爲。」他可能是對的,但我經常無法區分執行和行爲。我如何在我的測試中避免重複的代碼並避免嘲笑自我?

我還有一個例子(以Python樣式的僞代碼),可能會導致有用的答案:

class Consumer: 

    def spec_dirpath: 
     client = VCS.get_connection(self.vcs_client_name) 
     client.sync() 
     return client.dirpath() 

    def spec_filepath: 
     filepath = os.path.join(spec_dirpath(), self.spec_filename) 
     if not os.path.exists(filepath): 
      raise ConsumerException 
     return filepath 

    def get_components: 
     return Components.get_components_from_spec_file(self.spec_filepath()) 

這裏的想法是,get_components方法調用spec_filepath方法,以獲得一個路徑get_components_from_spec_file組件類方法將從中讀取組件列表的文件。 spec_filepath方法又調用spec_dirpath,它同步來自VCS系統的包含spec文件的目錄,並將路徑返回到該目錄。 (儘量不要找蟲子在此代碼 - 這是僞代碼,畢竟。)

我正在尋找如何測試這些方法的建議......

測試spec_dirpath應該是很簡單的。我可以模擬VCS類並讓它返回一個模擬對象並確認調用了適當的方法(並且spec_dirpath方法返回模擬的dirpath方法返回的內容)。

但是,如果我不模擬spec_dirpath在測試spec_filepath,我怎麼避免spec_filepath測試從spec_dirpath代碼複製相同的測試代碼?如果我在測試get_components時不模擬spec_filepath,如何避免從spec_filepath spec_dirpath中複製測試代碼?

回答

1

單元測試更適合某種形式的依賴注入。在這種情況下,因爲您要在代碼中創建客戶端,所以您需要在測試中創建一個依賴項,這需要某種形式的動態模擬來應對。 (在這種情況下,我們會使用部分模擬來模擬創建依賴的調用,以避免也要測試這些依賴)。

如果你注入啓動時的依賴(即傳入客戶對象),那麼你可以很容易地嘲笑它,而不是有重大的困難測試只是一個類。

所以,你需要或者部分模擬或依賴注入的解決方案,以實現這些目標。

1

通常在單元測試中,行爲是指外部可觀察到的行爲。

使用您的例子中,觀察到的行爲將是你從回來的組件列表。他們來自一個文件的事實是實現,因此我建議圍繞您獲取的組件列表構建您的測試,而不要嘲笑文件檢索,因爲它是該類的內部,並使用設置代碼提供適當的文件。

另一種方法是,使該組分從一個依賴加載的類文件,例如使其成爲構造函數參數或方法參數,以允許文件在類的外部指定。在這種情況下,它將是外部的,所以我會嘲笑它,以確保您從中獲得一致的行爲,以確保您的課程正確使用它。