本文使用xUnit對ASP.NET Core WebAPI做單元測試,使用HttpClient的同步和異步請求,下面詳細介紹xUnit的使用過程:
一、建立示例項目

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return $"value:{id}";
}
// POST api/values
[HttpPost]
public ActionResult<string> Post(dynamic obj)
{
return $"姓名:{obj.Name},年齡:{obj.Age}";
}
}
使用.NET Core建立一個xUnit單元測試項目,如圖:
項目的模闆頁已經為我們添加好了xUnit的引用,不需要我們手動去NuGet導入了,現在從NuGet中添加Microsoft.AspNetCore.App和Microsoft.AspNetCore.TestHost,xUnit項目并添加WebAPI的項目引用,如下圖所示:
二、編寫單元用例
寫單元測試一般有三個步驟:Arrange,Act 和 Assert。
- Arrange 是準備階段,這個階段是準備工作,比如模拟資料、初始化對象等;
- Act 是行為階段,這個階段是用準備好的資料去調用要測試的方法;
- Assert 是斷定階段,就是把調用目标方法傳回的值和預期的值進行比較,如果和預期一緻說明測試通過,否則為失敗。
建立一個單元測試類:ValuesTest.cs;用于對ValuesController進行單元測試。
1、使用HttpClient進行Get請求測試,單元測試代碼如下:
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Newtonsoft.Json;
using System.Net;
using System.Net.Http;
using System.Net.Mime;
using System.Text;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
namespace WebAPI.xUnit
{
public class ValuesTests
{
public ValuesTests(ITestOutputHelper outputHelper)
{
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 三個步驟。
2、使用HttpClient進行Post請求測試,并用ITestOutputHelper輸出請求資訊,單元測試代碼如下:
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Newtonsoft.Json;
using System.Net;
using System.Net.Http;
using System.Net.Mime;
using System.Text;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
namespace WebAPI.xUnit
{
public class ValuesTests
{
public ValuesTests(ITestOutputHelper outputHelper)
{
var server = new TestServer(WebHost.CreateDefaultBuilder()
.UseStartup<Startup>());
Client = server.CreateClient();
Output = outputHelper;
}
public HttpClient Client { get; }
public ITestOutputHelper Output { get; }
[Fact]
public async Task Post_ShouldBe_OK()
{
var content = new StringContent(JsonConvert.SerializeObject(new { Name = "cxt", Age = 22 }), Encoding.UTF8, MediaTypeNames.Application.Json);
var response = await Client.PostAsync("/api/values", content);
// Output
var responseTest = await response.Content.ReadAsStringAsync();
Output.WriteLine(responseTest);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
}
}
3、運作測試用例,得到測試結果。
在目前的方法内,如GetById_ShouldBe_Ok()、Post_ShouldBe_OK()代碼塊内右鍵->運作測試,或者打開測試資料總管,運作所選測試
綠色的勾表示已經測試通過。
下面檢視Post請求的Output列印結果:
通過上面兩個測試用例,發現使用起來超級友善。