當對代碼進行測試的時候, 咱們常常須要用到一些模擬(mock)技術.html
綠色的是須要被測試的類, 黃色是它的依賴項, 灰色的無關的類git
在一個項目裏, 咱們常常須要把某一部分程序獨立出來以便咱們能夠對這部分進行測試. 這就要求咱們不要考慮項目其他部分的複雜性, 咱們只想關注須要被測試的那部分. 這裏就須要用到模擬(Mock)技術.github
由於, 請仔細看. 咱們想要隔離測試的這部分代碼對外部有一個或者多個依賴. 因此編寫測試代碼的時候, 咱們須要提供這些依賴. 而針對隔離測試, 並不該該使用生產時用的依賴項, 因此咱們使用模擬版本的依賴項, 這些模擬版依賴項只能用於測試時, 它們會使隔離更加容易.算法
綠色的是須要被測試的類, 黃色是Mock的依賴項數據庫
使用Mock技術, 能夠有以下的優勢:編程
Mock技術一般在單元測試中使用, 可使用xUnit來爲.NET Core應用作單元測試, 這裏有介紹xUnit的文章: http://www.javashuo.com/article/p-rqwpmfqu-gm.html框架
那麼什麼是一個單元? 函數
這個一般是由團隊對系統的理解決定, 能夠針對一個類, 也能夠針對多個類.單元測試
單元測試一般具備如下特色:測試
還有其它的一些術語就不介紹了, 主要是這四個.
對於Stub 和 Mock ,能夠看下面兩張圖例:
官網: https://github.com/moq/moq4
Moq框架能夠用來建立dummy, stub 和 mock. 在本文裏把這三個東西都叫作mock對象吧.
Moq使用一套API來建立stub和mock對象.
一個簡單的.NET Core控制檯項目: https://github.com/solenovex/Moq-Tutorial-Code, 代碼是裏面的01 before.
該項目很是簡單, 是關於球員轉會業務, 它目前只有三個類.
TransferApplication, 球員轉會申請類:
TransferResult, 轉會審批結果枚舉:
還有TransferApproval, 轉會審批類:
'
當前的邏輯是, 發起球員轉會申請後, 進行審批: 若是總費用大於預算, 那麼就直接拒絕; 若是總費用不超標, 而且球員小於30歲, 那麼就批准; 但若是球員大於30歲, 而且是超級巨星的話, 這將由老闆決定.
在解決方案裏創建一個xUnit類型的項目:
而後要保證該項目所用到的庫都保持最新:
最後別忘了添加對FootballManager項目的引用:
打開Text Explorer, 能夠看到裏面有一個待測的單元測試:
把UnitTest1改爲下面這個簡單的單元測試:
從新Build後, 能夠看到單元測試的名稱更新了.
點擊Run All, 運行單元測試, 結果成功:
隨後再添加一個簡單的單元測試:
Build, 後就會出現這個測試:
Run All, 測試也會成功:
這時, 有一些需求的變化, 球員轉會審批前, 須要經過體檢.
首先在轉會申請類裏面添加兩個球員的屬性:
而後添加一個體檢的接口:
這兩個方法的做用是同樣的, 可是調用方法略有不一樣.
可是此時, 該接口的實現類尚未開發完畢:
在轉會審批類裏面, 須要添加這個依賴, 使用的是接口:
在單元測試類裏面, 我爲轉會球員添加了這兩個屬性, 可是審批類會報錯, 由於沒有加入依賴項:
因此測試的時候須要注入這個依賴項IPhysicalExamination, 可是PhysicalExamination類尚未作完(裏面的方法都沒有實現), 因此咱們沒法new出來這個類.
這時, 咱們也許能夠傳null進去?
這時, 項目是不報錯了.
跑單元測試, Run All:
測試失敗, 拋出NullReferenceException. 而這個異常致使了測試沒法正常進行.
因此, 咱們須要Moq, 它能夠提供一個Mock(模擬)版本的IPhysicalExamination, 並把它傳遞到審批類的構造函數裏.
在單元測試項目添加Moq:
Moq的第一篇先到這.