SuperAPI AI Directory

dotnet-testing-advanced-webapi-integration-testing

Testing & quality

View repository

Updated 10-16 09:16

About this skill

WebApi Integration Testing

Learning Objectives

After completing this skill, you will be able to:

  1. Build a complete WebApi integration testing architecture
  2. Use IExceptionHandler to implement modern exception handling
  3. Validate the ProblemDetails and ValidationProblemDetails standard formats
  4. Use Flurl to simplify URL building for HTTP tests
  5. Use AwesomeAssertions for precise HTTP response validation
  6. Set up a multi-container (PostgreSQL + Redis) test environment

Core Concepts

IExceptionHandler - Modern Exception Handling

The IExceptionHandler interface introduced in ASP.NET Core 8+ provides a more elegant way to handle errors than traditional middleware.GlobalExceptionHandler Based on the exception type (KeyNotFoundException → 404, ArgumentException → 400, others → 500), it generates the corresponding ProblemDetails response.

ProblemDetails Standard Format

The unified error response format defined by RFC 7807:

Field Description
type URI of the problem type
title Brief error description
status HTTP status code
detail Detailed error explanation
instance URI of the instance where the problem occurred

ValidationProblemDetails - For Validation Errors

Inherits from ProblemDetails and additionally contains an errors dictionary that records the validation error message for each field.

FluentValidation Exception Handler

The FluentValidation exception handler implements the IExceptionHandler interface and specifically handles ValidationException, converting validation errors into the standard ValidationProblemDetails format response. Handlers execute in the order they are registered, and specific handlers (such as FluentValidation) must be registered before the global handler.

For the complete implementation code, see references/exception-handler-details.md

Integration Testing Infrastructure

The test infrastructure consists of three core components:

  • TestWebApplicationFactory: Inherits WebApplicationFactory<Program>, configures multiple containers (PostgreSQL + Redis) and DI replacements (such as FakeTimeProvider)

    FakeTimeProvider is shared by all tests in the Collection and can only move forward; do not reset it to a fixed starting point at the beginning of each test, and instead calculate time assertions using Factory.TimeProvider.GetUtcNow() .

  • IntegrationTestCollection: Collection Fixture definition, ensuring container sharing

  • IntegrationTestBase: Test base class, providing HttpClient, DatabaseManager, FlurlClient, and time control methods

For the complete infrastructure code, see references/test-infrastructure.md

Flurl Simplifies URL Building

// 傳統方式
var url = $"/products?pageSize={pageSize}&page={page}&keyword={keyword}";

// 使用 Flurl
var url = "/products"
    .SetQueryParam("pageSize", 5)
    .SetQueryParam("page", 2)
    .SetQueryParam("keyword", "特殊");

Test Examples

Covers complete test examples such as successfully creating a product (201 Created), validation errors (400 BadRequest + ValidationProblemDetails), resource not found (404 NotFound + ProblemDetails), and paged queries (200 OK + PagedResult), as well as the TestHelpers data management strategy.

For complete test examples and data management code, see references/test-examples.md

Best Practices

1. Test Structure Design

  • Single Responsibility: Each test focuses on one specific scenario
  • 3A Pattern: Clearly distinguish Arrange, Act, Assert
  • Clear Naming: Method names express test intent

2. Error Handling Verification

  • ValidationProblemDetails: Verify error response format
  • ProblemDetails: Verify business exception responses
  • HTTP Status Codes: Confirm correct status codes

3. Performance Considerations

  • Container Sharing: Use Collection Fixture
  • Data Cleanup: Clean up data after tests, do not rebuild containers
  • Parallel Execution: Ensure test independence

Dependencies

<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" />

Project Structure

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

Output Format

  • Generate TestWebApplicationFactory.cs, configure multiple containers (PostgreSQL + Redis) and DI replacement
  • Generate IntegrationTestCollection.cs and IntegrationTestBase.cs test infrastructure
  • Generate DatabaseManager.cs, integrate Respawn for test data cleanup
  • Generate controller test classes, verify CRUD, ProblemDetails and ValidationProblemDetails
  • Generate GlobalExceptionHandler.cs and FluentValidationExceptionHandler.cs exception handlers

Reference Resources

Example Files

Original Article

The content of this skill is distilled from the "Old-School Software Engineer's Testing Training - 30-Day Challenge" article series:

Official Documentation

Related Skills

  • dotnet-testing-advanced-aspnet-integration-testing - ASP.NET Core Basic Integration Testing
  • dotnet-testing-advanced-testcontainers-database - Database Container Testing
  • dotnet-testing-advanced-testcontainers-nosql - NoSQL Container Testing
  • dotnet-testing-fluentvalidation-testing - FluentValidation Testing