Search code examples
c#asp.net-coretestingentity-framework-corexunit

Cannot remove DBContext from DI


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.


Solution

  • 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: