引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
引言
在上一章節我們實戰了在Asp.Net Core
中的項目實戰,這一章節講解一下如何測試Asp.Net Core
的中間件。
TestServer
還記得我們在集成測試中提供的TestServer
嗎?
TestServer
是由 Microsoft.AspNetCore.TestHost
包提供的。包含了用於在測試環境中模擬 ASP.NET Core
應用程式的類和方法。通過使用 TestServer
,開發人員可以在測試中模擬整個應用程式的運行環境,包括中間件的執行,從而進行集成測試和端到端測試。
中間件可以使用 TestServer
單獨測試。 這樣便可以:
- 實例化只包含需要測試的組件的應用管道。
- 發送自定義請求以驗證中間件行為。
優點:
- 請求會發送到記憶體中,而不是通過網路進行序列化。
- 這樣可以避免產生額外的問題,例如埠管理和
HTTPS
證書。 - 中間件中的異常可以直接流回調用測試。
- 可以直接在測試中自定義伺服器數據結構,如
HttpContext
。
實戰
VS
新建測試項目dotNetParadise.MiddlerWareTest
Nuget
安裝Microsoft.AspNetCore.TestHost
PM> NuGet\Install-Package Microsoft.AspNetCore.TestHost -Version 8.0.4
既然我們是要測試中間件 那首先得先在我們的Sample.Api
中創建一個中間件
定義MyMiddleware
中間件
public class MyMiddleware(RequestDelegate next)
{
public async Task InvokeAsync(HttpContext context)
{
// 在請求處理前執行的邏輯
context.Response.ContentType = "text/plain";
context.Response.Headers.TryAdd("X-Custom-Header", "CustomValue");
await context.Response.WriteAsync("Test My Middleware");
// 調用下一個中間件
await next(context);
// 在請求處理後執行的邏輯
await context.Response.WriteAsync("Middleware Test Completed");
}
}
定義測試類
// Arrange
using var host = await new HostBuilder()
.ConfigureWebHost(webBuilder =>
{
webBuilder
.UseTestServer()
.ConfigureServices(services =>
{
// 在這裡可以註入服務
})
.Configure(app =>
{
app.UseMiddleware<MyMiddleware>();
});
})
.StartAsync();
// Act
var response = await host.GetTestClient().GetAsync("/");
// Assert
response.EnsureSuccessStatusCode(); // 確保請求成功
var responseContent = await response.Content.ReadAsStringAsync();
Assert.Contains("Test My Middleware", responseContent);
Assert.Contains("Middleware Test Completed", responseContent);
Run Test
使用 HttpContext 發送請求
可以使用 TestServer
來設置測試環境,並創建一個模擬的 HttpContext
對象來代表一個請求
[Fact]
public async Task TestMiddleware_ExpectedResponse()
{
using var host = await new HostBuilder()
.ConfigureWebHost(webBuilder =>
{
webBuilder
.UseTestServer()
.ConfigureServices(services =>
{
})
.Configure(app =>
{
app.UseMiddleware<MyMiddleware>();
});
})
.StartAsync();
var server = host.GetTestServer();
server.BaseAddress = new Uri("http://localhost");
var context = await server.SendAsync(c =>
{
c.Request.Method = HttpMethods.Get;
c.Request.Path = "/";
c.Request.Host = new HostString("localhost");
c.Request.Scheme = "http";
});
//act
Assert.True(context.RequestAborted.CanBeCanceled);
Assert.Equal(HttpProtocol.Http11, context.Request.Protocol);
// 驗證響應
Assert.Equal(StatusCodes.Status200OK, context.Response.StatusCode);
var customHeader = context.Response.Headers["X-Custom-Header"].ToString();
Assert.Equal("CustomValue", customHeader);
}
使用 SendAsync
的好處包括:
通過設置 HttpContext
的任何屬性,從而精確控制請求的各個方面。相比於使用 HttpClient
,SendAsync
通常更快,因為它繞過了網路層。
集成測試:這是測試整個請求處理管道(包括所有中間件)的好方法。
然而,它也有一些限制:
局限性:
SendAsync
主要用於集成測試,而不是單元測試。它測試的是整個請求處理流程,而不是單個組件。
模擬限制:雖然你可以設置 HttpContext
的許多屬性來模擬請求,但某些方面(如用戶認證狀態或外部依賴項)可能難以完全模擬。
添加請求路由
這個比較好理解,就是在TestServer
中添加路由的功能和Asp.Net Core
中添加路由基本一致
[Fact]
public async Task TestWithEndpoint_ExpectedResponse()
{
using var host = await new HostBuilder()
.ConfigureWebHost(webBuilder =>
{
webBuilder
.UseTestServer()
.ConfigureServices(services =>
{
services.AddRouting();
})
.Configure(app =>
{
app.UseRouting();
//app.UseMiddleware<MyMiddleware>();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/hello", () =>
TypedResults.Text("Hello Tests"));
});
});
})
.StartAsync();
var client = host.GetTestClient();
var response = await client.GetAsync("/hello");
Assert.True(response.IsSuccessStatusCode);
var responseBody = await response.Content.ReadAsStringAsync();
Assert.Equal("Hello Tests", responseBody);
}
在測試場景中,添加請求路由的好處主要體現在以下幾個方面:
-
模擬真實環境:
通過添加請求路由,你可以模擬出與真實生產環境相似的請求處理流程。這使得測試更加接近實際使用情況,從而提高了測試的可靠性和有效性。 -
控制測試的粒度:
你可以針對特定的路由進行精確測試,確保每個路由都能正確響應並返回預期的結果。這有助於發現潛在的路由錯誤或邏輯問題,提高了測試的精度。 -
隔離測試:
在測試過程中,你可以通過配置路由來隔離特定的功能或組件,從而避免其他部分的干擾。這種隔離測試有助於更準確地定位問題,提高了測試的效率。 -
模擬異常場景:
通過配置路由,你可以模擬各種異常場景,如路由不存在、參數錯誤等。這有助於測試應用程式在異常情況下的響應和處理能力,提高了應用程式的健壯性。 -
自動化測試:
在自動化測試框架中,添加請求路由可以使得測試用例更加易於編寫和執行。通過發送請求到特定的路由並驗證響應,你可以自動化地檢查應用程式的功能和性能。
最後
本章我們探討瞭如何在Asp.Net Core
項目中測試中間件的方法和技巧。通過使用TestServer
和HttpContext
發送請求,我們可以模擬整個應用程式的運行環境,從而進行集成測試和端到端測試。同時,我們也介紹瞭如何添加請求路由來模擬不同的場景,並對中間件的行為進行驗證。
通過測試中間件,我們可以確保其在處理請求時的行為符合預期,提高應用程式的穩定性和可靠性。測試不僅可以幫助發現潛在的問題,還可以在開發過程中及早發現和解決 bug,提高代碼質量和開發效率。