I am writing XUnit integration tests for my ASP.NET Core Web API. I reconfigure my app in CustomWebApplicationFactory
to replace original DbContext
with the EFCore InMemoryDataBase
like this:
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
var context = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(DartsDbContext));
if (context != null)
{
services.Remove(context);
var options = services.Where(r => (r.ServiceType == typeof(DbContextOptions))
|| (r.ServiceType.IsGenericType && r.ServiceType.GetGenericTypeDefinition() == typeof(DbContextOptions<>))).ToArray();
foreach (var option in options)
{
services.Remove(option);
}
}
services.AddDbContext<DartsDbContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
});
});
}
I get this error:
One or more errors occurred. (Services for database providers 'Npgsql.EntityFrameworkCore.PostgreSQL', 'Microsoft.EntityFrameworkCore.InMemory' have been registered in the service provider. Only a single database provider can be registered in a service provider
If I delete the line of code in Program.cs
file that adds the original DbContext
, it works because only one DbContext
exists.
I want to save my original DbContext
injection in Program.cs
and I want CustomWebApplicationFactory
to replace it just for tests.
It seems that since .NET 9 (EF Core 9) IDbContextOptionsConfiguration<TContext>
(introduced in .NET 9) should be removed also:
var optionsConfig = services.Where(r => r.ServiceType.IsGenericType && r.ServiceType.GetGenericTypeDefinition() == typeof(IDbContextOptionsConfiguration<>))
.ToArray();
foreach (var option in optionsConfig)
{
services.Remove(option);
}
Current version of the docs for Customize WebApplicationFactory
seems to be invalid and there is an issue about it raised @github.
See also: