Удалить DbContext из DI. Тестирование с помощью WebApplicationFactory

#c# #entity-framework #asp.net-core #integration-testing

#c# #entity-framework #asp.net-ядро #интеграция-тестирование

Вопрос:

Сценарий — .net core 5 Web API, сервисы.AddDbContext используется в Startup.cs ConfigureServices для добавления SQL server. В тесте используется WebApplicationFactory, предоставляемый MVC testing, я хотел бы заменить DbContext на InMemory или указать на тестовую базу данных.

Я попытался удалить его в WebApplicationFactory ConfigureWebHost, но что-то удерживает SQL DbContext, потому что при выполнении теста он попадает на SQL server вместо базы данных InMemory, хотя SQL DbContext отсутствует в DI.

 builder.ConfigureTestServices(
 services =>
      {
           var serviceDescriptor = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(DbContext));
           if (serviceDescriptor != null)
           {
                services.Remove(serviceDescriptor);
           }
      }
 

Есть ли правильный способ заменить DbContext, добавленный в Startup.cs, в тестовом проекте?

Ответ №1:

Найдено решение. Вы должны удалить свой класс, производный от DbContext, и все DbContextOptions.

Пример

   services =>
  {
      var context = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(MyDbContext));
      if (context != null)
      {
          services.Remove(context);
          var options = services.Where(r => (r.ServiceType == typeof(DbContextOptions))
            || (r.ServiceType.IsGenericType amp;amp; r.ServiceType.GetGenericTypeDefinition() == typeof(DbContextOptions<>))).ToArray();
          foreach (var option in options)
          {
              services.Remove(option);
          }
      }

      services.AddDbContext<MyDbContext>(opt => opt.UseInMemoryDatabase(@"TestDB"));
  });