Переопределить EF Core DbContext в ASP.NET Core WebApplicationFactory

У меня есть проект ASP.NET Core 2.2 WebApi, который также использует EF Core 2.2. Проект протестирован с помощью интеграционных тестов с WebApplicationFactory<T>.

Я попытался перенести проект веб-API на netcore / aspnetcore 3, и это сработало очень хорошо. Я наткнулся на перенос тестов.

У меня есть следующий код, который работал в aspnetcore 2.2:

    public class MyServiceWebHostFactory : WebApplicationFactory<Service.Startup>
    {
        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {   
            builder.ConfigureServices(services =>
            {
                var serviceProvider = new ServiceCollection()
                                   .AddEntityFrameworkInMemoryDatabase()
                                   .BuildServiceProvider();

                services.AddDbContext<MyContext>((options, context) =>
                {
                    context.UseInMemoryDatabase("MyDb")
                           .UseInternalServiceProvider(serviceProvider);
                });

                var sp = services.BuildServiceProvider();

                using var scope = sp.CreateScope();

                var scopedServices = scope.ServiceProvider;

                // try to receive context with inmemory provider:
                var db = scopedServices.GetRequiredService<MyContext>();

                // more code...

                // Ensure the database is created.
                //db.Database.EnsureCreated();

                // more code...
            });
        }
    }

Он заменяет EF Core DbContext на DbContext с помощью InMemoryProvider.

После перехода на 3.0 он больше не заменяется. Я всегда получаю DBContext с настроенным SQL Server.

Если я удалю вызов services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString)) в ConfigureServices приложения (Service.Startup), он будет работать, но это не решение.

Я также попробовал services.RemoveAll(typeof(MyContext)) перед регистрацией контекста inmemory, который тоже не работает.


comment
Можете ли вы опубликовать DbContext (конструктор и OnConfigure)?   -  person BanditoBunny    schedule 30.10.2019
comment
Вы можете попробовать services.RemoveAll(typeof(DbContextOptions<MyContext>));.   -  person Yuri Cardoso    schedule 20.09.2020


Ответы (1)


Обновленная документация на https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-3.1 может помочь. Изменение ключевого фрагмента заключается в удалении предыдущей регистрации контекстной службы:

// Remove the app's ApplicationDbContext registration.
var descriptor = services.SingleOrDefault(
    d => d.ServiceType ==
        typeof(DbContextOptions<ApplicationDbContext>));

if (descriptor != null)
{
    services.Remove(descriptor);
}

// Add ApplicationDbContext using an in-memory database for testing.
services.AddDbContext<ApplicationDbContext>(options =>
{
    options.UseInMemoryDatabase("InMemoryDbForTesting");
});

// Build the service provider.
var sp = services.BuildServiceProvider();
person eugenecp    schedule 24.12.2019