您好,登錄后才能下訂單哦!
本篇內容主要講解“xUnit 如何編寫 ASP.NET Core 單元測試”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“xUnit 如何編寫 ASP.NET Core 單元測試”吧!
還記得 .NET Framework 的 ASP.NET WebForm 嗎?那個年代如果要在 Web 層做單元測試簡直就是災難啊。.NET Core 吸取教訓,在設計上考慮到了可測試性,就連 ASP.NET Core 這種 Web 或 API 應用要做單元測試也是很方便的。其中面向接口和依賴注入在這方面起到了非常重要的作用。
本文就來手把手教你如何用 xUnit 對 ASP.NET Core 應用做單元測試。.NET Core 常用的測試工具還有 NUnit 和 MSTest,我本人習慣用 xUnit 作為測試工具,所以本文用的是 xUnit。
創建示例項目
先用 ASP.NET Core API 模板建一個應用。
模板為我們自動創建了一個 ValuesController,為了方便演示,我們只留其中一個 Get 方法:
public class ValuesController : ControllerBase { // GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) { return "value"; } }
然后再添加一個 xUnit 單元測試項目:
模板自動為我們添加好了 xUnit 引用:
<ItemGroup> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" /> <PackageReference Include="xunit" Version="2.4.0" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> </ItemGroup>
但要測試 ASP.NET Core 應用還需要添加兩個 NuGet 包:
Install-Package Microsoft.AspNetCore.App
Install-Package Microsoft.AspNetCore.TestHost
當然還要引入目標項目。最后的引用是這樣的:
<ItemGroup> <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.5" /> <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.1.1" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" /> <PackageReference Include="xunit" Version="2.4.0" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\WebApplication1\WebApplication1.csproj" /> </ItemGroup>
添加完引用后編譯一下,確認引用沒有問題。
編寫單元測試
寫單元測試一般有三個步驟:Arrange,Act 和 Assert。
Arrange 是準備階段,這個階段是準備工作,比如模擬數據、初始化對象等;
Act 是行為階段,這個階段是用準備好的數據去調用要測試的方法;
Assert 是斷定階段,就是把調用目標方法返回的值和預期的值進行比較,如果和預期一致說明測試通過,否則為失敗。
按照這個步驟我們來編寫一個單元測試方法,以 ValuesController 中的 Get 方法作為要測試的目標。一般一個單元測試方法就是一個測試用例。
我們在測試工程添加一個 ValuesTests 單元測試類,然后編寫一個單元測試方法,代碼如下:
public class ValuesTests { public ValuesTests() { var server = new TestServer(WebHost.CreateDefaultBuilder() .UseStartup<Startup>()); Client = server.CreateClient(); } public HttpClient Client { get; } [Fact] public async Task GetById_ShouldBe_Ok() { // Arrange var id = 1; // Act var response = await Client.GetAsync($"/api/values/{id}"); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); } }
這里我們通過 TestServer 拿到一個 HttpClient 對象,用它我們可以模擬 Http 請求。我們寫了一個非常簡單的測試用例,完整演示了單元測試的 Arrange,Act 和 Assert 三個步驟。
建議單元測試的方法名使用“什么應該是什么”的模式。比如上面的 GetById_ShouldBe_Ok,表示調用 GetById 這個 API 返回的結果應該是 OK 的,這樣一看就知道你這個測試用例是干嗎的,不需要過多的注釋。
運行單元測試
單元測試用例寫好后,打開“Test Explore”(中文版 VS 看到的是中文),在測試方法上右擊,選擇“Run Seleted Tests”,也可以在方法代碼塊內鼠標右擊選擇“Run Tests”:
注意看測試方法前面圖標的顏色,目前是藍色的,表示測試用例還沒有運行過。
測試用例執行結束后如果結果和預期一致就是綠色的圖標:
如果運行結果和預期不一致就會是紅色圖標,然后你需要修改代碼直到出現綠色圖標。你可以在“Test Explore”的下方看到執行消耗的時間,也可以在 Output 窗口看到執行的細節。
以上圖標顏色的變化過程是:藍色,紅色,再綠色,有可能藍色經過一次運行就直接變成綠色,也有可能經過很多次紅色才變成綠色。測試驅動開發中的 BRG(藍紅綠)術語就是這么來的。
調試單元測試
你可以通過添加斷點的方式在單元測試中調試。方法很簡單,在需要調試的方法上右鍵選擇“Debug Seleted Tests”即可,和平時的調試是一樣的。
如果我們要查看 API 具體返回了什么,可以通過加斷點調試來查看返回結果的變量字符串值,但這種方式不是最好的選擇。比如對于同一個 API,我要看看 10 種參數返回的結果是什么樣的,每次都通過斷點調試來查看就很麻煩。
除了添加斷點來調試,還有一種打印日志的方法來快速調試,xUnit 可以很方便地做到這一點。為此我們來修改一ValuesTests:
public ValuesTests(ITestOutputHelper outputHelper) { var server = new TestServer(WebHost.CreateDefaultBuilder() .UseStartup<Startup>()); Client = server.CreateClient(); Output = outputHelper; } public ITestOutputHelper Output{ get; } // ... (省略其它代碼)
這里我們在構造函數中添加了 ITestOutputHelper 參數,xUnit 會將一個實現此接口的實例注入進來。拿到這個實例后,我們就可以用它來輸出日志了:
[Fact] public async Task GetById_ShouldBe_Ok() { // Arrange var id = 1; // Act var response = await Client.GetAsync($"/api/values/{id}"); // Output var responseText = await response.Content.ReadAsStringAsync(); Output.WriteLine(responseText); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); }
運行(注意不是 Debug)此方法,運行結束后,在“Test Explore”的下方可以可以看到“Output”字樣,點擊它就可以看到輸出的結果,如圖:
通過這種方式,每次運行測試我們就可以很方便的查看輸出結果了。
其它
上面我們是通過模擬 Http 請求的方式來調用 API 測試的,還有一種就是 new 一個 Controller 來直接調用它的 Action 方法來測試。比如這樣:
// Arrange var id = 1; var controller = new ValuesController(); // Act var result = controller.Get(id);
如果 Controller 沒有其它依賴,這種方式當然是最方便的。但通常 Controller 是會有一個或多個依賴的,比如這樣:
public class ValuesController : Controller { private readonly ISessionRepository _sessionRepository; public ValuesController(ISessionRepository sessionRepository) { _sessionRepository = sessionRepository; } // ... }
我們就要模擬實例化這個 Controller 的所有依賴,當然手動模擬是不現實的,因為一個依賴類還可能會依賴其它的類或接口,依賴鏈可能很長,你不可能每個依賴都手動去實例化它們。有一個叫 Moq 的工具可以自動來模擬實例化依賴,它的用法是這樣的:
// .. // Arrange var mockRepo = new Mock<ISessionRepository>(); mockRepo.Setup(...); var controller = new HomeController(mockRepo.Object); // Act var result = await controller.Index();
這種方式我是不推薦的,因為拋開 Moq 的學習成本不說,重要的是它不如模擬 Http 請求那樣接近真實的調用場景,所以本文對它不作過多的介紹,大家知道有這么回事就行。
到此,相信大家對“xUnit 如何編寫 ASP.NET Core 單元測試”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。