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

XUnit集成测试无法识别控制器Action,请求返回NotFound

问题描述

我用XUnit做API项目的集成测试,通过继承WebApplicationFactory的ApplicationFactory创建测试客户端。目前能正常访问MapGet定义的/test端点,但请求控制器中配置的api/v1/test/get接口时,始终返回HttpStatusCode.NotFound。想问下集成测试里请求控制器Action需要额外配置吗?


测试项目代码

private ApplicationFactory Factory { get; }

public AccountsControllerTests(ITestOutputHelper output)
{
    Factory = new ApplicationFactory(output);
}
[Fact]
public async Task ListBalancesTest()
{
    var client = Factory.CreateClient(new WebApplicationFactoryClientOptions(){AllowAutoRedirect = false});

    var resp = await client.GetAsync($"api/v1/test/get");
    //!!!!!!! resp.StatusCode is HttpStatusCode.NotFound !!!!!!!

    var mapgetResp= await client.GetAsync($"/test");
    //!!!!!!! mapgetResp is Working !!!!!!!
    Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
}

API代码

[ApiController]
[Route("api/v1/test")]
public class TestController : ControllerBase
{
    [HttpGet("get")]
    public async Task<ActionResult> Get()
    {
        return await Task.FromResult(Ok("Response from test"));
    }
}

ApplicationFactory代码

public class ApplicationFactory : WebApplicationFactory<TestStartup>
{
    public ApplicationFactory(ITestOutputHelper testOutput = null)
    {
        _testOutput = testOutput;
    }

    protected override IWebHostBuilder CreateWebHostBuilder()
    {
        var builder = WebHost
            .CreateDefaultBuilder()
            .UseEnvironment("Development")
            .UseStartup<TestStartup>()
            .UseSerilog();

        if (_testOutput != null)
        {
            builder = builder.ConfigureLogging(logging =>
            {
                logging.Services.TryAddEnumerable(
                    ServiceDescriptor.Singleton<ILoggerProvider>(new TestOutputHelperLoggerProvider(_testOutput)));
            });
        }

        return builder;
    }

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.UseContentRoot(".");

        builder.ConfigureServices(services =>{
            /...../
        });
    }
}

Startup代码

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapGet("/test", async context =>
    {
        await context.Response.WriteAsync(@$"Test value from MapGet");
    });
    /..../
});

可能的原因及解决办法
  1. 控制器未被正确发现:检查TestStartup的ConfigureServices方法,确保添加了services.AddControllers()而非仅AddMvcCore()——后者默认不包含控制器自动发现逻辑。
  2. 内容根路径错误:ApplicationFactory中builder.UseContentRoot(".")可能指向了错误目录,导致测试项目无法找到API控制器程序集。可以移除该配置(WebApplicationFactory默认会处理内容根路径),或指定API项目的实际物理路径。
  3. 路由配置异常:在开发环境下启用路由调试,查看实际注册的路由列表。需要先安装Microsoft.AspNetCore.Routing.Debugger包,然后在Startup的Configure方法中添加:
    if (env.IsDevelopment())
    {
        app.UseRoutingDebug();
    }
    
  4. 程序集引用问题:确保测试项目直接引用了API项目,或者TestStartup所在程序集能加载到包含TestController的API程序集。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 00:06:24