- Go語言精進之路:從新手到高手的編程思想、方法和技巧(2)
- 白明
- 967字
- 2022-01-04 17:42:22
第44條
正確運用fake、stub和mock等輔助單元測試
你不需要一個真實的數(shù)據(jù)庫來滿足運行單元測試的需求。
——佚名
在對Go代碼進行測試的過程中,除了會遇到上一條中所提到的測試代碼對外部文件數(shù)據(jù)的依賴之外,還會經(jīng)常面對被測代碼對外部業(yè)務組件或服務的依賴。此外,越是接近業(yè)務層,被測代碼對外部組件或服務依賴的可能性越大。比如:
- 被測代碼需要連接外部Redis服務;
- 被測代碼依賴一個外部郵件服務器來發(fā)送電子郵件;
- 被測代碼需與外部數(shù)據(jù)庫建立連接并進行數(shù)據(jù)操作;
- 被測代碼使用了某個外部RESTful服務。
在生產(chǎn)環(huán)境中為運行的業(yè)務代碼提供其依賴的真實組件或服務是必不可少的,也是相對容易的。但是在開發(fā)測試環(huán)境中,我們無法像在生產(chǎn)環(huán)境中那樣,為測試(尤其是單元測試)提供真實運行的外部依賴。這是因為測試(尤其是單元測試)運行在各類開發(fā)環(huán)境、持續(xù)集成或持續(xù)交付環(huán)境中,我們很難要求所有環(huán)境為運行測試而搭建統(tǒng)一版本、統(tǒng)一訪問方式、統(tǒng)一行為控制以及保持返回數(shù)據(jù)一致的真實外部依賴組件或服務。反過來說,為被測對象建立依賴真實外部組件或服務的測試代碼是十分不明智的,因為這種測試(尤指單元測試)運行失敗的概率要遠大于其運行成功的概率,失去了存在的意義。
為了能讓對此類被測代碼的測試進行下去,我們需要為這些被測代碼提供其依賴的外部組件或服務的替身,如圖44-1所示。

圖44-1 生產(chǎn)環(huán)境的真實組件或服務與測試環(huán)境的組件或服務的替身
顯然用于代碼測試的“替身”不必與真實組件或服務完全相同,替身只需要提供與真實組件或服務相同的接口,只要被測代碼認為它是真實的即可。
替身的概念是在測試驅(qū)動編程[1]理論中被提出的。作為測試驅(qū)動編程理論的最佳實踐,xUnit家族框架將替身的概念在單元測試中應用得淋漓盡致,并總結出多種替身,比如fake、stub、mock等。這些概念及其應用模式被匯集在xUnit Test Patterns[2]一書中,該書已成為測試驅(qū)動開發(fā)和xUnit框架擁躉人手一冊的“圣經(jīng)”。
在本條中,我們就來一起看一下如何將xUnit最佳實踐中的fake、stub和mock等概念應用到Go語言單元測試中以簡化測試(區(qū)別于直接為被測代碼建立其依賴的真實外部組件或服務),以及這些概念是如何促進被測代碼重構以提升可測試性的。
不過fake、stub、mock等替身概念之間并非涇渭分明的,理解這些概念并清晰區(qū)分它們本身就是一道門檻。本條盡量不涉及這些概念間的交集以避免講解過于瑣碎。想要深入了解這些概念間差別的讀者可以自行精讀xUnit Test Patterns。
- Puppet 4 Essentials(Second Edition)
- Vue.js設計與實現(xiàn)
- LabVIEW入門與實戰(zhàn)開發(fā)100例
- vSphere High Performance Cookbook
- Java設計模式及實踐
- Mastering Predictive Analytics with Python
- 實戰(zhàn)Java高并發(fā)程序設計(第3版)
- Python面向?qū)ο缶幊蹋簶嫿ㄓ螒蚝虶UI
- Highcharts Cookbook
- Lighttpd源碼分析
- C++從入門到精通(第5版)
- ServiceNow:Building Powerful Workflows
- Python程序設計與算法基礎教程(第2版)(微課版)
- Solutions Architect's Handbook
- 大學計算機基礎實驗指導