對於 Web API 的測試時,常常使用 Postman、Fiddler、Newman... 等工具進行測試,但是如果 Web API 和其他的服務 (如:Web API、資料庫) 耦合很高時,要完成這個測試勢必需要將相依的服務執行起來。因此本篇主要是要介紹如何在本機透過 Microsoft.AspNetCore.TestHost 對 Web API 進行測試。
環境
單元測試專案 (任選一種)
NET Core Web API 測試套件
Microsoft.AspNetCore.TestHost
Mock 測試套件 (可選)
宣告 TestServer、HttpClient、Configuration 三個物件
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.Configuration; using Xunit; public class DemoControllerTest { // Test Web API Host private readonly TestServer Server; // 主要用來呼叫 TestServer 時使用 private readonly HttpClient Client; // 提供 Web API 使用的組態設定,可使用測試用組態設定 private readonly IConfiguration Configuration; }
建立 Setup
[TestInitialize]
Attribute[SetUp]
Attribute設定 Configuration
建立 WebHostBuilder,設定執行環境、Configutation 和測試目標 (Web API 專案) 的 Startup 類別
設定 TestServer,Test Web API Host
設定 HttpClient,主要用來呼叫 TestServer 時使用的
最後,也可以在 Setup 和 Teardown 分別加入測試資料的準備和復原
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.Configuration; using Xunit; public class DemoControllerTest { private readonly TestServer Server; private readonly HttpClient Client; private readonly IConfiguration Configuration; public DemoControllerTest() { // 讀取 appsettings.json Configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .Build(); // 設定 Web Host,執行環境、Configutation、Web API 的 Startup 類別 var builder = new WebHostBuilder().UseEnvironment("Test") .UseConfiguration(Configuration) .UseStartup<Startup>(); // 建立 Test Server 和 Http Client Server = new TestServer(builder); Client = Server.CreateClient(); } }
[Fact] public async Task TestGetVersion() { // Arrange string url = "api/version"; string exceptionVersion = Configuration.GetSection("Version").Value.ToString(); // Act HttpResponseMessage response = await Client.GetAsync(url); string responseRaw = await response.Content.ReadAsStringAsync(); // Assert Assert.True(response.IsSuccessStatusCode); Assert.Equal(exceptionVersion, responseRaw); }
測試時可能會因為使用到一些從 Dependency Injection 注入的 Service,導致測試難以進行
在 SetUp 時,透過 ConfigureTestServices
替換掉相關的 Services
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Xunit; public class DemoControllerTest { private readonly TestServer Server; private readonly HttpClient Client; private readonly IConfiguration Configuration; public DemoControllerTest() { // 讀取 appsettings.json Configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .Build(); // 設定 Web Host,執行環境、Configutation、Web API 的 Startup 類別 var builder = new WebHostBuilder().UseEnvironment("Test") .UseConfiguration(Configuration) .UseStartup<Startup>(); // 替換掉相關的 Service,讓測試能夠順利進行 builder.ConfigureTestServices((services) => { services.AddSingleton<IMyService>(new MyMockService()); }); // 建立 Test Server 和 Http Client Server = new TestServer(builder); Client = Server.CreateClient(); } }
// 建立 Mock Service Mock<IMyService> testService = new Mock<IMyService>(MockBehavior.Strict); testService.Setup(g => g.GetResult()) .Returns("my-mock-result"); // 替換掉相關的 Service,讓測試能夠順利進行 builder.ConfigureTestServices((services) => { services.AddSingleton<IMyService>(testService.Object); });