You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用WebHostFactory HttpClient测试.NET Core API时出现404错误

问题:ASP.NET Core集成测试中API端点返回404 Not Found

我用WebHostFactory为ASP.NET Core应用搭建集成测试,已配置带自定义认证和内存数据库的测试服务器,此前的401未授权问题通过模拟认证解决,但当前调用API端点时持续返回404 Not Found。相关代码如下:

测试类代码

public class MyIntegrationTests : IClassFixture<WebApplicationFactory<Startup>>
{
    private readonly HttpClient _client;

    public MyIntegrationTests(WebApplicationFactory<Startup> factory)
    {
        _client = factory.WithWebHostBuilder(builder =>
             {
                 builder.ConfigureServices(services =>
                     {
                         var descriptor = services.SingleOrDefault(
                d => d.ServiceType ==
                        typeof(DbContextOptions<AppDbContext>));
                         services.Remove(descriptor);

                         services.AddDbContext<AppDbContext>(options =>
                             {
                                 options.UseInMemoryDatabase("InMemoryDbForTesting");
                             });

                         services.AddAuthentication("Test")
                             .AddScheme<AuthenticationSchemeOptions, TestAuthHandler>("Test", options => { });
                     });

        builder.Configure(app =>
        {
            app.UseRouting();
            app.UseCors();
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
            app.UseMiddleware<MockAuthenticationMiddleware>();
        });
    })
    .CreateClient(new WebApplicationFactoryClientOptions
    {
        AllowAutoRedirect = false,
    });

        _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Test");
    }
}

控制器代码

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[AllowAnonymous]
[Route("api/[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet("GetToday")]
    public IActionResult Get()
    {
        return Ok(new { Weather = "Sunny" });
    }
}

测试调用代码

[Given("the second number is (.*)")]
public async Task GivenTheSecondNumberIs(int number)
{
    _response = await _client.GetAsync("/api/WeatherForecast/GetToday");
    _response.EnsureSuccessStatusCode();
    var content = await _response.Content.ReadAsStringAsync();
    Assert.True(_response.IsSuccessStatusCode);
}

排查与解决思路

1. 修正中间件顺序

你将MockAuthenticationMiddleware放在了UseEndpoints之后,这会导致该中间件无法参与请求处理——端点匹配完成后,后续中间件不会再被执行。调整中间件顺序,将其移至UseAuthentication与UseAuthorization之间(或至少在UseEndpoints之前):

builder.Configure(app =>
{
    app.UseRouting();
    app.UseCors();
    app.UseAuthentication();
    app.UseMiddleware<MockAuthenticationMiddleware>(); // 调整位置
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
});

2. 确认控制器路由与程序集引用

  • 控制器路由api/[controller]结合动作路由GetToday,完整路径/api/WeatherForecast/GetToday是正确的,但需确保测试项目已引用Web项目,且WebApplicationFactory<Startup>使用的是Web项目中的Startup类,保证控制器程序集被正确加载。
  • 如果原项目Startup中存在额外路由配置(如MapControllerRoute),测试配置需同步保留,避免覆盖核心路由逻辑。

3. 避免完全重写中间件管道

若无需完全替换原项目的中间件配置,可改为在原管道基础上添加自定义中间件,而非重写整个Configure方法:

builder.Configure(app =>
{
    // 仅添加需要的自定义中间件,复用原项目的管道配置
    app.UseMiddleware<MockAuthenticationMiddleware>();
});

4. 验证端点注册状态

可在测试代码中添加日志或打印逻辑,确认测试服务器是否正确注册了控制器端点:

var server = factory.WithWebHostBuilder(...).Server;
var endpointDataSource = server.Services.GetService<IEnumerable<EndpointDataSource>>()?.FirstOrDefault();
if (endpointDataSource != null)
{
    foreach (var endpoint in endpointDataSource.Endpoints)
    {
        Console.WriteLine(endpoint.DisplayName);
    }
}

若未找到WeatherForecastController.Get相关端点,说明控制器未被正确注册,需检查项目引用或Startup类的控制器扫描配置。

内容的提问来源于stack exchange,提问作者Hasan Kanaan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 12:24:50