设置
- Windows 10
- Visual Studio 专业版 2017 v15.9.9
- ASP.NET 核心 2.2
- EF 核心 2.2
- 小巧玲珑
- xUnit 2.4.1
描述
我正在使用 Microsoft.AspNetCore.Mvc.Testing
包中的 WebApplicationFactory
来设置我的集成测试。
我一直在关注 official documentation自定义 Web 主机配置。
SUT 使用 Dapper 从数据库中查询,因此我没有使用 EF Core 附带的 In-Memory 提供程序来进行此特定集成测试。
我设置 WebApplictionFactory
的代码如下:
public class CustomWebApplicationFactory<TStartup>
: WebApplicationFactory<TStartup> where TStartup : class
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder
.UseStartup<TStartup>()
.ConfigureServices(services =>
{
var sp = services.BuildServiceProvider();
// Create a scope to obtain a reference to the database context
using (var scope = sp.CreateScope())
{
var scopedServices = scope.ServiceProvider;
var dbContext = scopedServices.GetRequiredService<MyDbContext>(); // <-- service not found
dbContext.Database.EnsureCreated();
new MyDbContextSeed()
.SeedAsync(dbContext)
.Wait();
}
});
}
}
问题
未找到 MyDbContext
服务,我明白为什么(我认为)- 因为我的 Startup.cs
类中的 ServiceProvider
没有'尚未建成。
但问题是我如何从此处的 Startup 类访问服务?
对于上下文,集成测试如下所示:
public class MyAPITests
: IClassFixture<CustomWebApplicationFactory<Startup>>
{
private readonly HttpClient _client;
private readonly CustomWebApplicationFactory<Startup> _factory;
public MyAPITests(CustomWebApplicationFactory<Startup> factory)
{
_factory = factory;
_client = factory.CreateClient();
}
[Fact]
public async Task Get_ItemAsync_WhenIdNotFound_ReturnsNotFoundStatusCode()
{
// Arrange
var request = new HttpRequestMessage(HttpMethod.Get, "api/v1/item/0");
// Act
var response = await _client.SendAsync(request);
// Assert
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
}
最佳答案
首先,ConfigureServices
可以代替UseStartup
,不能一起使用。其次,您无论如何都不应该在 ConfigureServices
期间创建作用域并进行迁移,而是在构建 Web 主机之后,参见 here :
In older tutorials, you may see similar code in the
Configure
method in Startup.cs. We recommend that you use the Configure method only to set up the request pipeline. Application startup code belongs in theMain
method.
唯一的办法不是在工厂里,而是在工厂建成之后:
public class MyAPITests
: IClassFixture<CustomWebApplicationFactory<Startup>>
{
private readonly HttpClient _client;
private readonly CustomWebApplicationFactory<Startup> _factory;
public MyAPITests(CustomWebApplicationFactory<Startup> factory)
{
_factory = factory;
_client = factory.CreateClient();
var host = factory.Server.Host;
using (var scope = host.Services.CreateScope())
{
var scopedServices = scope.ServiceProvider;
var dbContext = scopedServices.GetRequiredService<MyDbContext>();
dbContext.Database.EnsureCreated();
new MyDbContextSeed()
.SeedAsync(dbContext)
.Wait();
}
}
//...
}
关于c# - ASP.NET Core 2.2 集成测试 DbContext 服务未注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55812037/