当前位置:首页 > C# > 正文

使用 WebApplicationFactory 进行 C# 集成测试(.NET Core Web API 测试完整入门指南)

在现代软件开发中,集成测试是确保整个系统组件协同工作的关键环节。对于使用 C#ASP.NET Core 构建的 Web API 应用程序来说,微软提供的 WebApplicationFactory 是进行高效、真实环境模拟测试的强大工具。

本文将手把手教你如何使用 WebApplicationFactory 编写 C# 集成测试,即使你是测试新手,也能轻松上手!我们将涵盖项目搭建、测试类编写、依赖注入替换、HTTP 请求发送等核心内容。

使用 WebApplicationFactory 进行 C# 集成测试(.NET Core Web API 测试完整入门指南) C#集成测试 .NET API测试 ASP.NET Core测试教程 第1张

什么是 WebApplicationFactory?

WebApplicationFactory<TEntryPoint> 是 ASP.NET Core 提供的一个测试辅助类,它允许你在内存中启动一个真实的 Web 应用程序(无需监听端口),从而可以发送真实的 HTTP 请求并验证响应。这比单元测试更接近生产环境,但又比端到端测试更快、更可控。

准备工作:创建被测项目

首先,我们创建一个简单的 ASP.NET Core Web API 项目作为被测对象:

dotnet new webapi -n MyWebApi

然后进入项目目录,并添加一个简单的控制器:

// Controllers/WeatherController.csusing Microsoft.AspNetCore.Mvc;namespace MyWebApi.Controllers;[ApiController][Route("[controller]")]public class WeatherController : ControllerBase{    private static readonly string[] Summaries = new[]    {        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"    };    [HttpGet]    public IEnumerable<WeatherForecast> Get()    {        return Enumerable.Range(1, 5).Select(index => new WeatherForecast        {            Date = DateTime.Now.AddDays(index),            TemperatureC = Random.Shared.Next(-20, 55),            Summary = Summaries[Random.Shared.Next(Summaries.Length)]        })        .ToArray();    }}public class WeatherForecast{    public DateTime Date { get; set; }    public int TemperatureC { get; set; }    public string? Summary { get; set; }}

创建集成测试项目

在解决方案根目录下,创建一个 xUnit 测试项目:

dotnet new xunit -n MyWebApi.IntegrationTestsdotnet add MyWebApi.IntegrationTests reference MyWebApidotnet add MyWebApi.IntegrationTests package Microsoft.AspNetCore.Mvc.Testing

注意:必须安装 Microsoft.AspNetCore.Mvc.Testing 包,它包含了 WebApplicationFactory

编写第一个集成测试

在测试项目中创建一个测试类:

// WeatherControllerTests.csusing System.Net;using System.Text.Json;using MyWebApi;using Xunit;namespace MyWebApi.IntegrationTests;public class WeatherControllerTests : IClassFixture<WebApplicationFactory<Program>>{    private readonly WebApplicationFactory<Program> _factory;    public WeatherControllerTests(WebApplicationFactory<Program> factory)    {        _factory = factory;    }    [Fact]    public async Task GetWeather_ReturnsSuccessStatusCode_AndValidData()    {        // Arrange        var client = _factory.CreateClient();        // Act        var response = await client.GetAsync("/weather");        var responseString = await response.Content.ReadAsStringAsync();        var weatherForecasts = JsonSerializer.Deserialize<WeatherForecast[]>(responseString,            new JsonSerializerOptions { PropertyNameCaseInsensitive = true });        // Assert        Assert.Equal(HttpStatusCode.OK, response.StatusCode);        Assert.NotNull(weatherForecasts);        Assert.Equal(5, weatherForecasts.Length);    }    private record WeatherForecast    {        public DateTime Date { get; init; }        public int TemperatureC { get; init; }        public string? Summary { get; init; }    }}

关键点说明:

  • IClassFixture<WebApplicationFactory<Program>>:表示该测试类使用 WebApplicationFactory 作为共享上下文,每个测试类只启动一次应用。
  • _factory.CreateClient():创建一个 HttpClient,它会自动指向内存中的 Web 应用。
  • 我们发送 GET 请求到 /weather 并验证状态码和返回数据结构。

高级技巧:替换服务(Mock 依赖)

在真实项目中,你可能希望在测试时替换某些服务(例如数据库上下文、外部 API 客户端)。可以通过继承 WebApplicationFactory 并重写 ConfigureWebHost 方法实现:

// CustomWebApplicationFactory.csusing Microsoft.AspNetCore.Hosting;using Microsoft.AspNetCore.Mvc.Testing;using Microsoft.Extensions.DependencyInjection;namespace MyWebApi.IntegrationTests;public class CustomWebApplicationFactory : WebApplicationFactory<Program>{    protected override void ConfigureWebHost(IWebHostBuilder builder)    {        builder.ConfigureServices(services =>        {            // 移除原有服务(如果需要)            var descriptor = services.SingleOrDefault(                d => d.ServiceType == typeof(IMyService));            if (descriptor != null)                services.Remove(descriptor);            // 注入模拟服务            services.AddScoped<IMyService, MockMyService>();        });    }}// 在测试类中使用 CustomWebApplicationFactorypublic class WeatherControllerTests : IClassFixture<CustomWebApplicationFactory>{    private readonly CustomWebApplicationFactory _factory;    public WeatherControllerTests(CustomWebApplicationFactory factory)    {        _factory = factory;    }    // 测试方法保持不变...}

运行测试

在测试项目目录下运行:

dotnet test

如果一切配置正确,你应该看到测试通过!

总结

通过本教程,你已经掌握了如何使用 WebApplicationFactory 进行 C# 集成测试。这项技能对于构建可靠、可维护的 .NET Core Web API 至关重要。记住,良好的集成测试能大幅减少线上 bug,提升团队信心。

无论你是刚接触 ASP.NET Core测试教程 的新手,还是想优化现有测试的老手,WebApplicationFactory 都是你不可或缺的利器。赶快在你的项目中试试吧!

关键词回顾:C#集成测试、WebApplicationFactory、.NET Core Web API测试、ASP.NET Core测试教程