Testing on the Toilet:不要濫用Mock

柴阿峰發表於2013-06-14

本文選自 Google 的“Testing on the Toilet (TotT) ”章節。

在編寫測試程式碼的時候,單純的使用Mock來規避程式碼依賴性,執行測試是很容易的:

不過,如果我們不用Mock來實現測試程式碼的話,可能測試程式碼看起來更簡單,更有效:

上述程式碼就是濫用Mock的例子,濫用Mock類會帶來不少問題:

1. 測試程式碼可讀性很差

放棄直接使用你的被測產品程式碼邏輯(例如,直接把測試輸入傳遞給被測方法,然後檢查輸出),你需要編寫額外的程式碼以告訴Mock類如何行為。這些額外的程式碼實際上反映的是想如何進行測試,這些程式碼的可讀性通常很差,尤其是你不瞭解產品程式碼的內在實現的情況下。

2. 測試程式碼可維護性很差

當你告訴Mock類如何行為時,你就會把產品程式碼中的一些實現也帶入到測試程式碼中來。而一旦產品程式碼的實現發生了改變,你可能就需要對測試程式碼進行更新以適應產品程式碼的變更。而我們知道,典型的測試程式碼應該與被測試產品程式碼鬆耦合,測試程式碼應該著眼於被測程式碼的外部介面(而不是他們的實現)。

3. 測試程式碼對被測產品質量的保證水平也會降低(言外之意,測試程式碼的執行失敗不一定代表著被測試產品的質量有問題)

當你在測試程式碼中加入了過多的實現細節,那麼只有被測試程式碼嚴格符合你在Mock中描述的所有行為時,測試結果才正確。而這一點很難保證,尤其是如果被測試程式碼頻繁變更的情況下,因為被測試程式碼和測試程式碼做到實時同步是很困難的。

你在濫用Mock的一些跡象:你試圖在一個測試中Mock過多(超過一兩個)的類,或者你的Mock方法描述了過多(超過一兩個)方法的行為。亦或者,如果你在讀測試程式碼的時候,你發現需要了解被測試產品程式碼的實現才能讀懂,那麼,小心,你可能在濫用Mock。

有時你很難在測試中實現真正的獨立性(例如,可能使測試很慢,或者測試依賴於網路等硬體),但是在使用Mock之外你仍然有很多更好選擇,例如使用獨立的本地服務(例如,一個啟動在本地的模擬信用卡服務的應用)或者一個產品程式碼的偽實現(例如,一個駐留在記憶體中的信用卡服務程式)。

譯註:這是一個老生常談的話題,實際就是該用Stub用Stub,該用Mock用Mock。

 

英文原文: google testing blog, 翻譯: 柴阿峰

譯文連結: http://blog.jobbole.com/41342/

【非特殊說明,轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊,謝謝合作!】

相關文章