1. 程式人生 > >使用 Moq 測試.NET Core 應用 -- Mock 方法

使用 Moq 測試.NET Core 應用 -- Mock 方法

本文介紹使用Moq來Mock方法.

Mock 物件

緊接著上文中的例子. 上一篇文章, 我在單元測試的時候, 把依賴項設為null:

然後便出現了NullReferenceException, 導致測試無法正常執行.

首先應該做的是在TransferApproval的建構函式裡判斷引數是否為null, 如果為null的話應該丟擲ArgumentNullException:

這是更恰當的異常.

這樣的話, 在測試的時候, 丟擲的就是ArgumentNullException了, 它可以更恰當的表達程式出現的問題:

現在我們可以使用mock版本的依賴項來代替null了:

上面的程式碼首先使用Moq建立了一個mock版本的IPhysicalExamination的例項.

而由於Moq對依賴項進行了包裝, 所以要獲得實際的mock依賴項, 我們需要使用mockExamination.Object屬性. 而這個屬性的型別就是IPhysicalExamination.

另外一個測試方法我也這麼改一下, 然乎重新Build. Run All Tests:

還是紅色的, 但現在是測試沒通過, 並不是丟擲異常.

測試沒通過的意思就是期待值和實際返回值不符.

讓我們來除錯一下這個測試, 我在TransferApproval類裡面設定一個端點, 檢視一下這個mock依賴項的方法返回值:

然後除錯測試:

跑到斷點

可以看到這個Mock版本依賴項的IsHealthy()方法的返回值是false.

我並沒有對這個Mock版本的IPhysicalExamination的IsHealthy()方法設定返回值, 正因為如此, 它才會返回它方法返回型別的預設值, 它的返回型別是bool, 而bool的預設值是false, 所以現在IsHealthy()方法在沒有設定的情況下的返回值就是false.

It類

而PhysicalExamination這個具體的實現類由於各種原因導致還沒有實現, 為了讓它不妨礙我們的單元測試, 我先設定讓它在無論傳進什麼引數的情況下都會返回true.

從業務上來講就是假設所有轉會球員都可以通過體檢:

那麼現在所有的測試都應該可以通過了:

這裡用到了It這個類, 在Moq裡, It這個類是用來做引數匹配的, it 就是"它"的意思, 它就代表需要被匹配的引數. 

It.IsAny<T>(), 它表示傳遞給方法的引數的型別只要是T就可以, 值是任意的. 只要滿足了這個條件, 那麼方法的返回值就是後邊Returns()方法裡設定的值.

它有下面幾種用法:

  • Is<TValue>(Expression<Func<TValue, Boolean>>)
  • IsAny<TValue>()
  • IsIn<TValue>(IEnumerable<TValue>)
  • IsInRange<TValue>(TValue, TValue, Range)
  • IsNotIn<TValue>(IEnumerable<TValue>)
  • IsNotNull<TValue>()
  • IsRegex(string)

我認為通過方法名就可以知道這些方法的用途.

下面我修改一下該測試方法, 使用It其它幾個方法:

其測試結果仍然是通過的.

嚴謹(Strict) vs 寬鬆(Loose) Mock

Moq裡面有Strict(嚴謹)和Loose(寬鬆) mock物件的概念, 當然也有很多人不喜歡這個概念.

在當前的測試方法裡, TransferApproval依賴於Mock<IPhysicalExamination>, 並呼叫其IsHealthy()方法.

如果不對IsHealthy()方法進行任何設定的情況下, 方法會返回bool的預設值false, 這種就是loose(寬鬆) Mock.

在建立Mock物件的時候, 還可選傳遞一個MockBehavior這個引數.

MockBehavior是一個列舉, 它有三個值:

  • MockBehavior.Strict, 如果mock物件上的方法沒有被預先設定好, 那麼測試中呼叫該方法的時候就會丟擲異常.
  • MockBehavior.Loose, 即使方法沒有被預先設定, 呼叫它的時候也不會丟擲異常. 它會返回該方法返回型別的預設值.
  • MockBehavior.Default, 它代表MockBehavior.Loose.

如果上例使用Strict Mock, 那麼將會丟擲Exception:

下面我把一個測試改為Strict Mock, 並取消了對IsHealthy()方法的設定:

而測試時會丟擲MockException:

在對方法進行設定後, 測試就會通過:

可以感覺到:

Loose Mock, 可以少寫一些設定程式碼, 可以返回預設值, 不易讓測試中斷

Strict Mock, 需要寫跟多的設定程式碼, 每個被呼叫的方法都需要進行設定, 所以也更容易讓測試中斷.

Moq的建議是: 大多數情況下應該使用Loose Mock, 只有特殊需要的時候才去使用Strict Mock.

out引數

修改一下TransferApproval類的轉會審批方法:

這次使用的是帶有out引數的IsHealthy()方法.

建立一個測試方法, 並設定這個帶有out引數的方法:

很簡單, 測試會通過:

未完待續....

相關推薦

使用 Moq 測試.NET Core 應用 -- Mock 方法

本文介紹使用Moq來Mock方法. Mock 物件 緊接著上文中的例子. 上一篇文章, 我在單元測試的時候, 把依賴項設為null: 然後便出現了NullReferenceException, 導致測試無法正常執行. 首先應該做的是在TransferApproval的建構函式裡判斷引數是否

使用 Moq 測試.NET Core 應用 -- Mock 行為

src 進行 alt 狀態 執行 ref tro 調用次數 eal 第一篇文章, 關於Mock的概念介紹: https://www.cnblogs.com/cgzl/p/9294431.html 第二篇文章, 關於方法Mock的介紹: https://www.cnb

使用 Moq 測試.NET Core 應用 -- Mock 屬性

本文介紹Moq的使用. Mock屬性 屬性是指 get set property. 接著上文, 我在03 Before部分的程式碼裡做了一些修改. 首先IPhysicalExamination介面添加了IsMedicalRoomAvailable屬性: 其實現類: 屬性方法內依

使用 Moq 測試.NET Core 應用 -- 其它

表達 連續 span empty ups 通過 check lin 事件綁定 第一篇文章, 關於Mock的概念介紹: https://www.cnblogs.com/cgzl/p/9294431.html 第二篇文章, 關於方法Mock的介紹: https://www.c

使用 Moq 測試.NET Core 應用

 什麼是Mock 當對程式碼進行測試的時候, 我們經常需要用到一些模擬(mock)技術. 綠色的是需要被測試的類, 黃色是它的依賴項, 灰色的無關的類 在一個專案裡, 我們經常需要把某一部分程式獨立出來以便我們可以對這部分進行測試. 這就要求我們不要考慮專案其餘部分的複雜性, 我們只想關注需要被

使用 coverlet 查看.NET Core應用測試覆蓋率

針對 我只 dir rdo col 使用命令 str nbsp dex Visual Studio 2017的企業版可以直接查看測試的代碼覆蓋率, 而由於我只能用得起Visual Studio Community和VS Code所以不得不尋找其它的辦法來查看測試覆蓋率.

利用BenchmarkDotNet 測試 .Net Core API 同步和異步方法性能

ons 偏差 microsoft 指標 att 結果 ror 返回 嘗試 事由: 這兩天mentor給我布置了個任務讓我用BenchmarkDotNet工具去測試一下同一個API 用同步和異步方法寫性能上有什麽差別。 過程: 首先 我們需要在Nuget上安裝BenchMar

利用BenchmarkDotNet 測試 .Net Core API 同步和非同步方法效能

事由: 這兩天mentor給我佈置了個任務讓我用BenchmarkDotNet工具去測試一下同一個API 用同步和非同步方法寫效能上有什麼差別。 過程: 首先 我們需要在Nuget上安裝BenchMarkDotNet (安裝當前最新版本,當前我已經安裝好了) 但是卻安裝失敗出現兩個error。 其中一個是

Moq 在.net Core 單元測試中的使用

Moq,主要用來偽造介面的實現類,實現方法,屬性 moq The most popular and friendly mocking framework for .NET What? Moq (pronounced "Mock-you" or just "Mock") is the onl

使用 coverlet 檢視.NET Core應用測試覆蓋率

程式碼覆蓋(Code coverage)是軟體測試中的一種度量,描述程式中原始碼被測試的比例和程度,所得比例稱為程式碼覆蓋率。 Visual Studio 2017的企業版可以直接檢視測試的程式碼覆蓋率, 而由於我只能用得起Visual Studio Community和VS Code所以不得不尋找其它的免

5種設定ASP.NET Core應用程式URL的方法

預設情況下,ASP.NET Core應用程式監聽以下URL: - http://localhost:5000 - https://localhost:5001 在這篇文章中,我展示了5種不同的方式來更改您的應用程式監聽的URL。 - 在Program.cs中使用 `UseUrls()` - 環境變數

Linux使用Jexus托管Asp.Net Core應用程序

技術 文件目錄 只需要 true 沒有 repr tag 博文 env 第一步 安裝.Net Core環境 安裝 dotnet 環境參見官方網站 https://www.microsoft.com/net/core。 選擇對應的系統版本進行安裝。安裝完成過後 輸入命令查

在 Azure WebApps 中運行64位 Asp.net Core 應用

需求 正常 mmu www. module .config 正在 external doc 作為微軟下一代的開源的跨平臺的開發框架, Asp.net core 正在吸引越來越多的開發者基於其構建現代 web 應用。 目前, Azure App Service 也實現了對 a

Centos7環境下使用Nginx托管.Net Core應用程序

erro else hid dev 直接 update 谷歌瀏覽器 rod ins 一、安裝.Net Core 參考官方文檔:https://www.microsoft.com/net/core#linuxcentos 1、添加dotnet產品Feed 在安裝.NET C

運行Vue在ASP.NET Core應用程序並部署在IIS上

生產環境 所在 來講 一個 重寫 文章 .net core 設置 分享 前言 從.NET Core 1.0開始我們就將其應用到項目中,但是呢我對ASP.NET Core一些原理也還未開始研究,僅限於會用,不過園子中已有大量文章存在,借著有點空余時間,我們來講講如何利用AS

教你如何實現微信小程序與.net core應用服務端的無狀態身份驗證

做的 動圖 ef7 服務端 apt 是我 分布 .net service 隨著.net core2的發布,越來越多人使用.net core2開發各種應用服務端,下面我就結合自己最近開發的一款小程序,給大家分享下,怎麽使用小程序登錄後,小程序與服務端交互的權限控制。

將ASP.NET Core應用程序部署至生產環境中(CentOS7)

for linux home web 虛擬 direct director block bic 閱讀目錄 環境說明 準備你的ASP.NET Core應用程序 安裝CentOS7 安裝.NET Core SDK for CentOS7。 部署ASP.NET

使用Docker部署ASP.NET Core應用程序實踐

4.0 cor run .com cnblogs pda word 本地配置 問題 前言 最近把很火的Docker給看了,於是就磨拳擦掌要去實踐一下。於是就拿之前一個aps.net core的項目(已被停止)去練手。該項目之前在ubuntu14.04上確保可以正常運行,所以

在 Docker 中部署 ASP.NET CORE 應用

post netcore 工作 ros core 指定 們的 本地 body 有了 Docker 之後, 部署起來卻這間非常方便,環境不用搭了, 直接創建一個 microsoft/aspnetcore 的容器, 在本地開發好後, 把內容直接部署到容器中。 下面的命令是把本

新建.Net Core應用程序後引用項一直黃色感嘆號怎麽辦?

右鍵 blog 消失 成功 黃色感嘆號 生成 重新 創建 正常 我們在vs中創建.Net Core應用程序後,引用項可能出現黃色感嘆號,正常情況下,這種黃色感嘆號時能在項目創建成功之後迅速消失的,可也有些時候一直不消失,怎麽辦? 我們可以選中異常的項目,然後右鍵菜單,選擇