对于 .net core 6 中的控制器调用,WebApplicationFactory 始终返回 404

Posted

技术标签:

【中文标题】对于 .net core 6 中的控制器调用,WebApplicationFactory 始终返回 404【英文标题】:WebApplicationFactory always return 404 for controllers calls in .net core 6 【发布时间】:2022-01-14 20:40:17 【问题描述】:

我按照 microsoft 的文档进行集成测试: https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-6.0#introduction-to-integration-tests

在 .net core 6 中,startup.cs 已被删除,我之前使用的集成测试不再按原样工作。我需要更新。

在我的 API csproj 中,我添加了:

<ItemGroup>
        <InternalsVisibleTo Include="Integration.Tests" />
</ItemGroup>

这里是 Integration.Tests csproj:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <IsPackable>false</IsPackable>
        <IsTestProject>true</IsTestProject>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
        <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.0" />
        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
        <PackageReference Include="xunit" Version="2.4.1" />
        <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
            <PrivateAssets>all</PrivateAssets>
        </PackageReference>
        <PackageReference Include="coverlet.collector" Version="3.1.0">
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
            <PrivateAssets>all</PrivateAssets>
        </PackageReference>
    </ItemGroup>

    

</Project>

我创建了一个 TestWebAppFactory.cs,例如:

public class TestWebAppFactory<TEntryPoint> : WebApplicationFactory<Program> where TEntryPoint : Program

    public ITestOutputHelper Output  get; set; 
    public List<string> Logs  get; private set;  = new List<string>();

    public TestWebAppFactory([NotNull] ITestOutputHelper output)
    
        Output = output;
    

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    
        builder
            .ConfigureServices(services =>
            
                var descriptor = services.SingleOrDefault(
                    d => d.ServiceType ==
                        typeof(DbContextOptions<MyDbContext>));

                if (descriptor != null)
                
                    services.Remove(descriptor);
                

                services.AddDbContext<MyDbContext>(options =>
                
                    options.UseInMemoryDatabase("My.Sample");
                );
            )
            .Configure(app =>  
                var serviceProvider = app.ApplicationServices;
                using var scope = serviceProvider.CreateScope();
                var itemManager = serviceProvider.GetRequiredService<IItemManager>();
                TestDbInitializer.Seed(scope.ServiceProvider, Output);
            );

    

还有我的 Item_Tests.cs:

public class Items_Tests : IClassFixture<Program>
    
        private readonly HttpClient _client;
        private readonly TestServer _server;
        private readonly IWebHost _host;

        public Items_Tests(ITestOutputHelper output)
        
            var factory = new TestWebAppFactory<Program>(output);
            _client = factory
                .CreateClient();
         

        [Fact]
        public async Task Index_WhenCalled_ReturnsApplicationForm()
        
            var response = await _client.GetAsync(Constants.Api.V1.Items.Url);

            response.EnsureSuccessStatusCode();

            var responseString = await response.Content.ReadAsStringAsync();

            Assert.Contains("Mark", responseString);
            Assert.Contains("Evelin", responseString);
        

    

注意:我希望能够将 ITestOuputHelper 发送到 TestWebAppFactory 以在输出中写入一些有用的信息,我不会在此处分享以减少代码量。

注意 2:当我启动 API 时,一切正常,我将在 Swagger 中查看我的控制器并使用代码 200 returnw 调用 get。

所以每次在这里测试失败:

            var response = await _client.GetAsync(Constants.Api.V1.Items.Url);

            response.EnsureSuccessStatusCode();

响应总是得到 404 错误。

我应该怎么做才能让它正常工作?

谢谢

【问题讨论】:

【参考方案1】:

所以最后我找到了为什么会出现 404,当我删除 TestWebAppFactory 中的 .Configure 部分时,我能够连接到 API。

所以现在我需要找到如何在测试期间播种数据 :)

【讨论】:

您了解更多吗?我在一个最小的项目上得到了 404。甚至不要配置WebHost。只是一个控制器端点返回 200 检查我在那里做了什么:github.com/ranouf/net60withnswag/tree/main/tests/… 也许它会帮助你,让我知道

以上是关于对于 .net core 6 中的控制器调用,WebApplicationFactory 始终返回 404的主要内容,如果未能解决你的问题,请参考以下文章

在.net core 6的导航栏中显示用户个人资料图片[关闭]

使用 .NET 6 在 ASP.NET Core 中处理 API 调用中的空子类

ASP.NET Core启动地址配置方法及优先级顺序 | .NET 6 版本 #yyds干货盘点#

ASP.NET Core - 在没有Ajax的情况下调用javascript中的控制器方法

对控制器函数的多次调用会导致问题(ASP.NET MVC Web 应用程序中的 EF Core)

asp.net core 系列6 实战之 一个项目的完整结构