從測試代碼回推生產代碼壞味道

前言

寫單元測試常碰到的兩種問題:

  1. dependency 的問題,導致無法隔離相依,無法模擬或驗證相依對象的互動
  2. 要模擬的相依對象太多

其實,這都是散發著壞味道的象徵。

本文

當在撰寫 isolated unit test 時發現,要 stub 的對象太多時,往往是兩種 bad smell 的徵兆。

  1. 單一職責的另一種 anti-pattern, 把一個職責過分拆細,導致要完成某一件事得組合太多零碎的相依對象才能運作。(比較常見)
  2. 測試目標對象 (SUT) 的職責過大,需要很多相依對象互動才能完成自己的職責。(機率較小)

另外要留意的一個要點,如果假對象都是 mock, 而非 stub, 那通常代表用錯了。

mock 是透過注入假對象,用來驗證測試目標與這個相依假對象之間的互動,也就是 assertion 的目的。而 stub 對象是用來模擬相依對象的動作,以便讓單元測試能獨立驗證測試目標對象本身的邏輯是否正確。

因為單元測試一次只測一件事,所以請勿同時對測試目標對象進行 assert, 又對 mock 對象進行 assert。因為這兩個 assert 的關注點,勢必是不同件事。

在《單元測試的藝術》一書上提到,mock 跟 stub 在實務上的比例大約是 5%:95%(個人經驗差不多是 10%:90%)。過多過細的 mock, 會讓 test cases 的穩定度 (Robustness) 下降, 孩子生了就得養,所以需要生的時候再生就好。

剛好的 mock, 可以有效降低測試用例幾倍的維護成本。

如果你非得驗證到 mock 對象互動所接收到的參數,請記得「只驗證意義,例如透過 regex pattern。而不是驗證參數的所有細節」

補充

測試用例的撰寫與維護,往往是 production code 設計品質的照妖鏡。如果你碰到以下的狀況,代表:

  1. 一個需求異動,要加好多的測試用例:代表違反單一職責與開放封閉原則,應該只需要新增 class 做切換,而不是對原本內容修改。
  2. 一個需求異動,要改好多測試用例:代表違反單一職責,一個對象的職責太大。
  3. 要 stub 的對象很多:代表違反單一職責,因為同一個職責被拆到太多對象身上,要做一件事就需要很多個對象一起,才能正常運作一件事。
  4. 互動的方式一改、參數一改,測試用例就壞:代表 mock 太深,mock 可以只驗證互動次數、參數的意義以及參數的完整內容,越後面代表綁得越深。
  5. UI 一改,所有測試用例都要跟著修改:layout 與 scenario 耦合性太高,請透過 page object pattern 從測試程式設計上解耦。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 原来我非不快乐 始2016.6.27 聽說,能到達金字塔頂端的只有兩種動物,一是雄鷹,靠著自己的...
    _行走中的蝸牛_阅读 1,670评论 1 8
  • 提問的智慧 How To Ask Questions The Smart Way Copyright © 2001...
    Albert陈凯阅读 2,896评论 0 8
  • 程序員創業白皮書 作者:Paul Graham Paul Graham是程序員,專欄作家。他在1995年創建了第一...
    刘立山John阅读 2,138评论 0 20
  • 隨筆1-24(2015.6-10) 1、作者 才華不是財富,痛苦不是財富,用才華對痛苦進行思考和表達才是。於是有了...
    四葉阅读 1,661评论 3 14
  • 【杯子技巧】 和對方的交情還屬於曖昧不清的階段,正確掌握和對方的距離感,是很困難的事。 最可怕的是,你覺得兩人的感...
    77733261dbff阅读 776评论 0 0

友情链接更多精彩内容