Как заменить IDbContextFactory при внедрении службы для интеграционного теста xUnit

#.net-core #dependency-injection #integration-testing #xunit

Вопрос:

Я настраиваю API с использованием .NET 5 с внедрением зависимостей для доступа к данным; сначала использую код Entity Framework. Мне нужно использовать IDbContextFactory, потому что некоторым моим контроллерам необходимо использовать более одного экземпляра DbContext для правильной единицы объема работы.

Я также пытаюсь использовать xUnit для интеграционных тестов и сталкиваюсь с трудностями при его использовании в базе данных памяти.

Вот соответствующий фрагмент из моего класса запуска

 public void ConfigureServices(IServiceCollection services)  {  services.AddDbContextFactorylt;ApplicationDbContextgt;(  options =gt; options.UseSqlServer("connection string")  );   //other services configured  }  

И это фабрика приложений xUnit, которая должна удалить существующий DbContextFactory и заменить его фабрикой памяти.

 public class TestApplicationFactorylt;TStartupgt;  : WebApplicationFactorylt;TStartupgt; where TStartup: class  {  protected override void ConfigureWebHost(IWebHostBuilder builder)  {  builder.ConfigureServices(services =gt;  {  var contextFactory = services.SingleOrDefault(  d =gt; d.ServiceType ==  typeof(IDbContextFactorylt;ApplicationDbContextgt;)  );  services.Remove(contextFactory);    services.AddDbContextFactorylt;ApplicationDbContextgt;(  options =gt; options.UseInMemoryDatabase("InMemoryDbForTesting")  );   var sp = services.BuildServiceProvider();  var dbf = sp.GetRequiredServicelt;IDbContextFactorylt;ApplicationDbContextgt;gt;();  var db = dbf.CreateDbContext();  db.Database.EnsureCreated();   // Pass the context to a class that will add seed data  DbSeed.InitializeDbForTests(db);  });  }  

Когда я выполняю отладку, кажется, что удаляется существующая фабрика, о чем свидетельствует количество служб, которые удаляются после служб.Удалите(ContextFactory); строку, и она также, кажется, добавляет новую, снова посмотрев на счетчик.

Это не вызывает никаких ошибок, это просто не использует новый DbContextFactory.

Что я здесь упускаю?

Заранее благодарю вас за любую помощь.

Ответ №1:

Я разобрался в этой проблеме.

Когда запускается класс запуска

 public void ConfigureServices(IServiceCollection services)  {  services.AddDbContextFactorylt;ApplicationDbContextgt;(  options =gt; options.UseSqlServer("connection string")  );   //other services configured  }  

На самом деле это добавление четырех дескрипторов в коллекцию служб:

  1.  IDbContextFactorylt;ApplicationDbContextgt;  
  2.  IDbContextFactorySourcelt;ApplicationDbContextgt;  
  3.  DbContextOptions  
  4.  DbContextOptionslt;ApplicationDbContextgt;  

Решение состоит в том, чтобы удалить все это в xUnit ApplicationFactory. Я снимал только один. Как только я удалил остальные три, я мог продолжить добавлять версию DbContextFactory в памяти, и теперь она правильно указывает на тестовую базу данных.

Если у вас есть более эффективное или элегантное решение, мне было бы интересно узнать.