ASP.NET Core WebApi 整合測試完整指南。涵蓋 WebApplicationFactory、IExceptionHandler、ProblemDetails 標準格式驗證。包含 Testcontainers 多容器編排、Flurl URL 建構、AwesomeAssertions HTTP 驗證。 Keywords: webapi integration testing,...
完成本技能學習後,您將能夠:
IExceptionHandler 實作現代化異常處理ProblemDetails 和 ValidationProblemDetails 標準格式ASP.NET Core 8+ 引入的 IExceptionHandler 介面提供了比傳統 middleware 更優雅的錯誤處理方式。GlobalExceptionHandler 依據例外類型(KeyNotFoundException → 404、ArgumentException → 400、其他 → 500)產生對應的 ProblemDetails 回應。
RFC 7807 定義的統一錯誤回應格式:
| 欄位 | 說明 |
|---|---|
type |
問題類型的 URI |
title |
簡短的錯誤描述 |
status |
HTTP 狀態碼 |
detail |
詳細的錯誤說明 |
instance |
發生問題的實例 URI |
繼承自 ProblemDetails,額外包含 errors 字典,記錄每個欄位的驗證錯誤訊息。
FluentValidation 異常處理器實作 IExceptionHandler 介面,專門處理 ValidationException,將驗證錯誤轉換為標準的 ValidationProblemDetails 格式回應。處理器之間按照註冊順序執行,特定處理器(如 FluentValidation)必須在全域處理器之前註冊。
完整實作程式碼請參閱 references/exception-handler-details.md
測試基礎設施由三個核心組件構成:
TestWebApplicationFactory:繼承 WebApplicationFactory<Program>,配置多容器(PostgreSQL + Redis)與 DI 替換(如 FakeTimeProvider)
FakeTimeProvider由 Collection 內所有測試共用,只能往前推;不要在每個測試開始時設回固定起點,時間斷言改以Factory.TimeProvider.GetUtcNow()推算。
IntegrationTestCollection:Collection Fixture 定義,確保容器共享
IntegrationTestBase:測試基底類別,提供 HttpClient、DatabaseManager、FlurlClient 與時間控制方法
完整基礎設施程式碼請參閱 references/test-infrastructure.md
// 傳統方式
var url = $"/products?pageSize={pageSize}&page={page}&keyword={keyword}";
// 使用 Flurl
var url = "/products"
.SetQueryParam("pageSize", 5)
.SetQueryParam("page", 2)
.SetQueryParam("keyword", "特殊");
涵蓋成功建立產品(201 Created)、驗證錯誤(400 BadRequest + ValidationProblemDetails)、資源不存在(404 NotFound + ProblemDetails)、分頁查詢(200 OK + PagedResult)等完整測試範例,以及 TestHelpers 資料管理策略。
完整測試範例與資料管理程式碼請參閱 references/test-examples.md
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="AwesomeAssertions" Version="9.4.0" />
<PackageReference Include="Testcontainers.PostgreSql" Version="4.11.0" />
<PackageReference Include="Testcontainers.Redis" Version="4.11.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0" />
<PackageReference Include="Flurl" Version="4.0.0" />
<PackageReference Include="Respawn" Version="7.0.0" />
src/
├── Api/ # WebApi 層
├── Application/ # 應用服務層
├── Domain/ # 領域模型
└── Infrastructure/ # 基礎設施層
tests/
└── Integration/
├── Fixtures/
│ ├── TestWebApplicationFactory.cs
│ ├── IntegrationTestCollection.cs
│ └── IntegrationTestBase.cs
├── Handlers/
│ ├── GlobalExceptionHandler.cs
│ └── FluentValidationExceptionHandler.cs
├── Helpers/
│ ├── DatabaseManager.cs
│ └── TestHelpers.cs
├── SqlScripts/
│ └── Tables/
└── Controllers/
└── ProductsControllerTests.cs
TestWebApplicationFactory.cs,配置多容器(PostgreSQL + Redis)與 DI 替換IntegrationTestCollection.cs 與 IntegrationTestBase.cs 測試基礎設施DatabaseManager.cs,整合 Respawn 進行測試資料清理GlobalExceptionHandler.cs 與 FluentValidationExceptionHandler.cs 異常處理器TestWebApplicationFactory,以 IAsyncLifetime 管理容器生命週期IntegrationTestBase 基底類別與 IntegrationTestCollection 共用容器設定DatabaseManager,負責測試資料庫的初始化與重置IExceptionHandler 的全域例外處理器ValidationProblemDetails。註冊順序需先於全域處理器本技能內容提煉自「老派軟體工程師的測試修練 - 30 天挑戰」系列文章:
dotnet-testing-advanced-aspnet-integration-testing - ASP.NET Core 基礎整合測試dotnet-testing-advanced-testcontainers-database - 資料庫容器測試dotnet-testing-advanced-testcontainers-nosql - NoSQL 容器測試dotnet-testing-fluentvalidation-testing - FluentValidation 測試