寫單元測試,我不認為是件容易的事


這是一個40多歲還在編碼的老程序員對單元測試的理解和實踐。里面沒有廢話,希望每句話能說到你心坎里。

原則:只測自己

自己的含義:方法邊界內的主體邏輯。一切下游方法、框架依賴、外部IO等都不是自己。如spring、 外部數據庫都視為外部邏輯。

這一原則的動機

便於定位

每個方法有自己獨立的單元測試,這有利於IDE在單元測試與邏輯代碼間跳躍,便於定位,並降低代碼結構調整的影響范圍。

不重復,降低復雜度

因每個方法有自己的單元測試,所以當前測試不要涵蓋下游方法的功能測試。以避免邏輯改動造成不必要的影響范圍擴大。

實踐與建議

要想單元測試更易於維護,良好的設計是前提

分層開發

開發也是可以分層的,先進行框架開發后進行具體開發。如先定義好所有的接口和要傳遞的數據,並組織好控制層,然后測試和具體開發便可同時展開。這樣便可提前發現結構性問題,提前對設計進行驗證,減少后期結構性調整對單元測試的影響。

單一職責

盡量應用單一職責設計模式,使邏輯模塊化,並使用老板原則將這些模塊串起來。這對於類的內部實現尤其重要,因為這會影響單元測試的覆蓋能力。

只有這樣每個方法的邏輯才能簡單,對應的單元測試自然便於維護。作為老板的控制類或方法不必苛求單元測試,可酌情選擇是否單元測試,因為控制是少數派,且實質邏輯已經被分攤到模塊中。

邏輯與外部IO分離

這是單一職責的延申,數據的加載、處理與輸出是可以作為獨立的三個職責的。其中數據的加載和輸出往往與外部環境依賴有關,本身的測試意義不大,即便測試也不能到處運行,且測試運行效率低下。

所以我們需要將IO邏輯從處理邏輯中剝離,並放到外層的控制邏輯中去並用mock來解決。這樣沒有外部依賴的處理邏輯——核心,將得到簡化,從而單元測試得到簡化。

如果中間實在需要外部IO可考慮在IO處進行邏輯拆分,這樣拆分后的子邏輯中就沒有了IO依賴,從而得到簡化。

到處運行

有時候單元測試是脫離不了環境的,如我們想驗證一下 SQL 的正確性。此時建議在單元測試上應用 @Disabled 注解,以便在 mvn test 中忽略這些測試,從而保證測試可以到處運行。

@Autowired

請盡量避免對框架的依賴,如 spring 的 @Autowired 注入機制,這會巨幅增加單元測試的構建難度,巨幅增加單元測試的耗時,因為這會對 mock 對象的注入造成困難。

建議,使用構造注入代替屬性注入,這樣就可以擺脫對 spring 的依賴。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM