隱藏在mock之後的‘快感’

      最近某同事抱怨他們的測試難寫,經常花費在測試的時間比產品代碼更多,而且每次重構後都必須修改一大堆的測試。和同事閒談後得知,在其項目中大量的使用了mock,或者說對mock的使用過度極端對所謂的單元測試“快速”,“獨立“的過度。 在前邊轉載過《軟件開發中沒有所謂正確的方法》,當你把某一種方法論作爲銀彈使用的時候,早晚魔鬼會伴隨在你身邊。

    Mock給我帶來了感知,剝離了類與類之間的依賴,有助於我們更好的工作在當前的關注點 .但同時由於太多的對場景的假設,導致這塊代碼成爲了信息的孤島,甚至很多時候不得不用mock的第二特性verify,order,以至於你的測試關心的不再是代碼存在的business邏輯,而傾向代碼層面的設計實現,這就把你單元測試推向了“白盒測試“的位置,導致測試變爲脆弱的測試。每當簡單的重構導致內部的變化,你的測試也必須隨着改變。

    鄙人認爲作爲一個好的測試而言,在一次合法的簡單重構之下,是不需要修改測試的,因爲你修改的只是內部實現,而不是business的改變,如果你邊改測試邊重構或者重構後掛到一大堆測試,這意味這你的測試不是一個穩定的測試或者你不是一次合法的重構(也許redesign,override)。

    在同事的項目中對mock的極端到了對簡單的View Object 也採用builder模式,可是內部卻全是mock given。在我看來而言View Object只是一個簡單的數據載體,不存在行爲邏輯,我們毫無必要去做mock,mock該是針對假設,而應該儘量避免對狀態mock。在同事的項目中導致需要寫一個測試之前,作爲測試的準備given ,必須理解存在代碼的實現,因爲你需要一堆given,比如對於person對象,如果你在實現中需要得到account則:

given(person.getAccount()).willReturn(some account);

    導致我需要了解實現需要什麼property,如果我需要新的的property也許只是簡單的把某個“依戀情結”放入了object,測試也需要被修改,導致重構者對自己的重構並不那麼自信,這將影響重構成爲日常行爲,隨着堆積的”壞味道“這將一點一點的侵蝕你的代碼,項目慢慢的也許會不能的不可控。

    Mock並不是一個壞的東西,結果的好壞在於使用的人,團隊 的意識,如果是mock anywhere或者杜絕mock走向兩個任意的極端都將是一個錯誤的抉擇。

    Mock更多的使用場景爲對外界資源解依賴增強感知能力,以及對無響應的重要business的驗證,後者長體現於一個沒有返回子void的method,但是method比如增加用戶積分,記錄用戶信息等的。然而對於有響應的business,我需要的不是mock而應該是assert,對於測試來說對於business來說應試是我的輸入應該得到我預期的響應,而非我verify某個行爲發生了,那麼其結果一定就正確,當然對於實現來說這是成立的,但是從測試的價值來說這廝無意義的,這將是一個脆弱的測試,我認爲一個好的測試將是“黑盒測試“,是一個business的描述,對一份約定,契約的闡述。

     附言,如果你因爲測試的速度,獨立性來爲自己的mock證明,那將是無意義的,不是每一個測試都必須在黃金法則內(0.1s),如果你對外部依賴,耗時依賴的分離,這我相信將不再是問題所在,測試的優化將是另一個有趣的話題,將不是本問內容之列。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章