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

前言

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

  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 從測試程式設計上解耦。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

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