通常,我們編寫的軟件會直接與那些我們稱之為“骯髒的”服務交互。通俗地說,服務對我們的應用來說是至關重要的,它們之間的交互是我們設計好的,但這會帶來我們不希望的副作用——就是那些在我們自己測試的時候不希望的功能。
比如,可能我們正在寫一個社交軟件並且想測試一下“發布到Facebook的功能”,但是我們不希望每次運行測試集的時候都發布到Facebook上。
Python的unittest庫中有一個子包叫unittest.mock——或者你把它聲明成一個依賴,簡化為mock——這個模塊提供了非常強大並且有用的方法,通過它們可以模擬或者屏敝掉這些不受我們希望的方面。
注意:mock是最近收錄在Python 3.3標准庫中的;之前發布的版本必須通過 PyPI下載Mock庫。
再舉一個例子,考慮系統調用,我們將在余下的文章中討論它們。不難發現,這些都可以考慮使用模擬:無論你是想寫一個腳本彈出一個CD驅動,或者是一個web服務用來刪除/tmp目錄下的緩存文件,或者是一個socket服務來綁定一個TCP端口,這些調用都是在你單元測試的時候是不被希望的方面。
作為一個開發人員,你更關心你的庫是不是成功的調用了系統函數來彈出CD,而不是體驗每次測試的時候CD托盤都打開。
作為一個開發人員,你更關心你的庫是不是成功調用了系統函數來彈出CD(帶著正確的參數等)。而不是體驗每次測試的時候CD托盤都打開(或者更糟,很多次,當一個單元測試運行的時候,很多測試點都涉及到了彈出代碼)。
同樣地,保持你的單元測試效率和性能意味著要還要保留一些自動化測試之外的“緩慢代碼”,比如文件系統和網絡的訪問。
對於我們的第一個例子,我們要重構一個從原始到使用mock的一個標准Python測試用例。我們將會證明如何用mock寫一個測試用例使我們的測試更智能、更快,並且能暴露更多關於我們的軟件工作的問題。