2011-05-07 36 views
6

假設您需要使用一個不必要的複雜,難以模擬(也許它具有沒有虛擬接口的具體類),以及不可靠的第三方庫,它與一些外部資源套接字或數據庫。您決定創建「包裝器」接口/類來大大簡化該庫的使用,並允許使用包裝器的開發人員繼續編寫可測試的代碼。包裝界面看起來沒有像原始界面。測試第三方庫的智能包裝

我有幾個關於如何測試這個包裝的問題。

  1. 包裝是否應該在沒有外部資源的情況下通過開發一個可以被模擬的不良庫的方法層方法來測試?

  2. 當您使用第三方庫(使用外部資源)測試包裝類時,這是單元測試還是集成測試?如果在自動化測試期間外部資源可以嵌入到內存中,它仍然是一個集成測試嗎?

  3. 在什麼時候我們放棄嘲笑和剔骨,並說我們有一個單位。根據wikipedia「一個單位是應用程序中最小的可測試部分」。但我覺得這很難衡量。如果速度是決定我們是否正在測試一個單元的一個因素,那麼如何判斷測試被稱爲單元測試的速度有多慢?

回答

9

TDD並沒有說所有的東西都必須經過單元測試。 TDD說你應該先寫一個測試,但不一定是單元測試。

  1. 從集成測試開始 - 它將測試您的邏輯依賴於將與真實組件通信的包裝器。這裏沒有嘲笑。這是集成測試,因爲它測試應用程序的多個層,而實際組件仍然使用套接字或數據庫訪問。
  2. ,因爲你沒有你的邏輯集成測試將失敗
  3. 與嘲笑包裝
  4. 編寫單元測試,測試邏輯
  5. ,因爲你沒有你的邏輯
  6. 編寫單元測試將失敗滿足單元測試的邏輯(4.)
  7. 重複3.-5。獲得所有必要的邏輯來滿足集成測試(1)
  8. 重複整個過程中的下一個集成測試

無需編寫單元測試的包裝。主包裝的功能是包裝組件。如果你爲包裝器編寫單元測試,你會測試它調用組件的方法,但是在這種情況下你又回到了開始 - 如何模擬組件?如果你編寫集成測試只是爲了調用組件的包裝器,你正在重新測試組件(OK,這有時是方便的,但在正常情況下,你不這樣做)。

我推薦閱讀Steve Freeman和Nat Pryce的Growing Object-Oriented Software guided by tests

5

我覺得這個問題都是圍繞着這樣的說法:

包裝器的界面看起來完全不像原來的接口

這可能表明有參與之間的轉換邏輯的顯著量包裝和原始界面。這聽起來很像anti-corruption layer,如果這個邏輯很複雜,就應該進行測試。

做到這一點的最好辦法仍然是提取1:從原來的API接口1。但是,這不是您暴露給應用程序其餘部分的界面。通過提取的接口,您公開給應用程序其餘部分的接口可以是Facade。從某種意義上說,你可以說提取的接口是反腐敗層的實現細節,而不是暴露給應用程序其餘部分的東西。

這使您能夠單元測試的門面接口和提取接口,同時仍保持原來的,難以測試組件進行的檢測之間的轉換。

剩下的就是提取的界面和原來的組件之間的轉換。但是,如果該接口被提取爲原始組件的1:1映射,則實現應該由純粹的委派組成。換句話說,實現將具有1的圈複雜度,因此是不需要單元測試的Humble Object

可能仍然需要在完成系統拋出了幾個集成或系統測試,但這些可能採取的煙霧測試的作用,因爲你應該已經從單元測試有足夠的覆蓋範圍。

+0

+1我想,如果包裝/門面最終被不僅僅是方法委託,它可能足夠複雜,足以證明創建1:1「啞」包裝來隔離邏輯的時間是合理的。非常好的一點。 – insipid 2011-05-09 13:25:29

2

廣告1)不是簡短的回答。包裝不應該做任何事情比包裝。因此集成測試是唯一有意義的事情。

廣告2)是的。

廣告3)停止時,你的對象有針對性的做的只有一件事,讓外界對象 - 注射mockable - 做一切(SRP)