对于 .net core 6 中的控制器调用,WebApplicationFactory 总是 return 404
WebApplicationFactory always return 404 for controllers calls in .net core 6
我按照微软的文档进行了集成测试:
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 returnsw 调用 get。
所以这里每次测试失败:
var response = await _client.GetAsync(Constants.Api.V1.Items.Url);
response.EnsureSuccessStatusCode();
响应总是出现 404 错误。
我应该怎么做才能使其正常工作?
谢谢
所以最后我找到了为什么我得到 404,当我删除 .Configure 部分时 TestWebAppFactory 我能够连接API.
所以现在我需要找到如何在测试期间播种数据:)
我按照微软的文档进行了集成测试: 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 returnsw 调用 get。
所以这里每次测试失败:
var response = await _client.GetAsync(Constants.Api.V1.Items.Url);
response.EnsureSuccessStatusCode();
响应总是出现 404 错误。
我应该怎么做才能使其正常工作?
谢谢
所以最后我找到了为什么我得到 404,当我删除 .Configure 部分时 TestWebAppFactory 我能够连接API.
所以现在我需要找到如何在测试期间播种数据:)