「To Mock or Not to Mock」 — 談開始測試的 Force
前陣子收到一位讀者的來信,他針對我的書「你就是不寫測試才會沒時間」的內容,問了我一些延伸的問題。
我覺得這些問題應該是大部份要在工作上開始加入單元測試的人都多多少少會遇到的,所以直接寫成文章,直接回應該讀者的同時,也讓部落格的其他讀者,如有類似問題的,也能一起得到解答。
此為第三題:
這個問題我想從 B 開始講起。Mock 這東西(為了方便,請容我用 Mock 一詞來代替所有測試替身,而忽略其分類),一開始要鎖定一個已經做好的類,甚至是其中的一兩個 method 為目標來測試時,是蠻方便的。也就是說,如果你的系統測試很少,而你不想一下子把測試範圍拉得太大時,是一個不錯的工具,可以幫你快速達到一定程度的保護目的。
但是隨著你系統中的測試越來越完整,你的信心理應越來越大,這時,你對「重構」就會開始躍躍欲試。而我相信 Kent Beck 等所有大師都會同意我下面這句話:「就去重構吧!」
「重構」,才是你的單元測試真正發揮效用的時候!
但這時你發現,過去寫的測試因為 Mock 太多,而使得架構的調整變得很辛苦。這是 Mock 的問題嗎?嗯…私以為,追根究柢,這應該要算是「測試粒度」的問題。
上一篇,我們說到測試應該要以一個功能為目標,而不是一個類,或是一個方法。所以,是因為測試粒度放太小,這才使得被依賴的對象不得不用 Mock 技術來取代。
筆者書中有提到「好控制的用真的,不好控制的用假的」,指的是受測對象所依賴的物件,何時要注入真的,何時要注入一個 Mock。試想,當你所有依賴都是用真的物件,你的測試涵蓋範圍是不是就很大了?如果是,那無形中這些依賴的功能也就一口氣被你測到了,這時,這些依賴在一樣場景的表現也就不用自己再測一次了。
我知道,這些細節我的書中沒有提到。但畢竟兩年過去了,當時的知識量跟現在也不一樣了…也許有機會出二版的話,我會把這些補充進去…有機會的話啦… XD
但我也沒出什麼大 bug 呀!
只能說這位讀者真的很強!一個 Developer 一生從不出大包的,自古以來少矣。真的是很厲害!
不過,如同筆者一再強調,測試的最大價值並不在保護功能。測試的最大價值其實是落在幫助重構。你永遠不出大 Bug,那你真的很有本事,但你不太可能在沒有測試保護的情況下大膽重構。因為 QA 沒空理你。
如 Kent Beck 在 Tidy First? 書中說的,重構不是在給功能,重構是在給選擇。你今天重構越小步,就能越常重構(一天十幾次這種「常」);而越常重構,當面臨需求改變,你的技術選擇就會越多;最後,技術選擇越多,你就老是能夠選擇最適合當下的設計。
而不用像以前一樣,屈就於已經不再適合的設計,讓整個系統內到處都是 workaround。
套句 91 大大常說的,有用就會有用,沒用就會沒用。學得再多,不真正落實,是絕對感受不到好處的。沒感受過好處的人,當然不覺得這東西有用囉!
Just Do It!
Reference
- Kent Beck, Tidy First?: https://www.amazon.com/Tidy-First-Personal-Exercise-Empirical/dp/1098151240
More about Me
- 更多軟體工程相關討論:https://www.facebook.com/kukumamaya
- 我的YouTube 頻道:https://www.youtube.com/@yu-songsyu6598
- 沒時間寫測試?沒時間重構?你就是不寫測試才會沒時間: https://www.tenlong.com.tw/products/9786263332645?list_name=lv