第一篇文章, 關於Mock的概念介紹: http://www.javashuo.com/article/p-rjikmmye-ha.htmlhtml
第二篇文章, 關於方法Mock的介紹: http://www.javashuo.com/article/p-bbgioyks-mg.htmlgit
第三篇文章, 關於屬性Mock的介紹: http://www.javashuo.com/article/p-vrvqgofk-mh.htmlgithub
第四篇文章, 關於行爲Mock的介紹: http://www.javashuo.com/article/p-hwcygjfb-mh.html測試
本文介紹使用Moq其它一些功能.ui
使用的代碼: https://github.com/solenovex/Moq4-Tutorial-Code 裏面的 05 Before 部分.spa
這裏是指讓mock對象拋出異常.3d
首先建立一個測試方法, 並設定球員年齡小於16歲時, IPhysicalExamination會在調用IsHealthy()方法時拋出異常:htm
隨後在球員審批的方法裏, 須要捕獲這個異常, 並返回相應的結果:對象
這個測試會經過:blog
上面使用的是泛型的版原本拋出異常, 也能夠不使用泛型, 直接拋出異常:
咱們還可讓mock對象來引發事件.
首先在IPhysicalExamination添加一個event:
每當IsHealthy()方法被調用後, 就應該引發這個event事件.
在實現類裏, 也須要加上這個event, 可是暫時不對它作任何其它動做:
在轉會審批類裏, 作這樣幾處修改:
添加一個處理事件的方法, 若是事件被觸發, 那麼PlayerHealthChecked這個標識就會變成true.
建立一個測試方法, 以判斷該event是否被觸發:
這個測試應該會失敗:
由於該event並無被觸發(PhysicalExamination裏並沒作什麼動做).
這時, 咱們可使用mock對象來觸發該事件, 在測試方法裏, 手動調用mock對象的Raise()方法:
第一個參數是lambda表達式, 該事件綁定到null, 第二個參數針對本例是EventArgs.Empty便可.
再測試, 就會經過:
第二種方法是在設置IsHealthy()方法的時候對事件進行觸發設定:
這樣的話只要IsHealthy()方法被調用, 那麼HealthChecked這個事件也會被觸發.
該測試也會經過:
使用SetupSequence()方法能夠爲mock對象的成員在連續調用的時候每次都返回指定的值(或拋出指定的異常):
該測試執行時, 第一次調用IsHealthy()方法時, 該方法返回true, 體檢經過; 而第二次調用IsHealthy()方法時, 返回false, 體檢不經過.
這個測試是會經過的:
首先創建一個類, 它沒有實現任何接口, 裏面有一個方法用於判斷當前是否處於轉會期:
而後在轉會審批類裏使用該類:
建立一個測試方法, mock上面的類:
可是該測試回失敗:
這是由於Moq在mock這種類的時候要求其方法必須是virtual的.
那麼修改該方法爲virtual:
這樣的話測試就會經過:
爲上面的類再添加一個protected virtual 方法:
若是想要mock這個方法的話, 須要這樣用:
有參數的話, 須要用到ItExpr類.
咱們能夠把以前寫的設定代碼使用Linq的方式來寫:
這裏要使用Mock.Of<T>()方法. 參數的lambda表達式裏面能夠設定mock對象成員的返回值.
因爲這種方法直接返回所需的類型, 因此在使用mock對象的時候就無需使用.Object屬性了.
該測試也會經過:
Moq的簡介就到這裏, 其實看官方文檔會更快速一些: https://github.com/Moq/moq4/wiki/Quickstart
重構後的代碼在: https://github.com/solenovex/Moq4-Tutorial-Code 裏面的05 After.