-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
This is related, I think, to the confusion expressed in dotnet/efcore#17224. No matter what I try, I cannot get an InMemoryDatabase into the service collection for an ASP.NET Core app. This was a scenario that was working by following the docs, but isn't working since I moved to 3.0.
Steps to reproduce
I'm using the code from this directory in my repository: https://github.com/OdeToCode/explore-aspnetcore/tree/master/All/test/TestTheTest
You should be able to download the folder and dotnet build / dotnet test the solution.
The idea is to run integration tests against an ASP.NET Core application by swapping out a DbContext configured to use SQL Server with a DbContext configured for in-memory. The web app configures services like so:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<SomeDbContext>(options =>
{
options.UseSqlServer("fail");
});
}
The tests use a custom WebApplicationFactory in an attempt to override the DbContext options.
public class CustomWebFactory : WebApplicationFactory<Startup>
{
protected override IHostBuilder CreateHostBuilder()
{
return Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(c =>
{
c.UseStartup<Startup>();
});
}
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
services.AddDbContext<SomeDbContext>(options =>
{
options.UseInMemoryDatabase("DB");
});
});
}
}
The test in the project uses a simple piece of middleware to look at the configured provider for the DbContext at runtime.
public async Task Invoke(HttpContext ctx, SomeDbContext db)
{
if (ctx.Request.Path.StartsWithSegments("/db"))
{
await ctx.Response.WriteAsync(db.Database.ProviderName);
}
else
{
await next(ctx);
}
}
I am able to override and change other services in the WebApplicationFactory
, except for the DbContext options. The only technique that seems to work is to remove the call to options.UseSqlServer
in the web app - then the factory override does take hold. From what I can tell, execution never reaches the options builder of the test factory, so no combination of service caching and UseInternalProvider
work.
Further technical details
EF Core version: 3.0.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer and InMemory
Target framework: .NET Core 3.0
Operating system: Win10-x64
IDE: VS2019