【问题标题】:How to replace IDbContextFactory in Service Injection for xUnit integration test如何在服务注入中替换 IDbContextFactory 以进行 xUnit 集成测试
【发布时间】:2022-01-01 12:19:54
【问题描述】:

我正在使用带有依赖注入的 .NET 5 设置一个 API,用于我的数据访问;首先使用实体​​框架代码。我需要使用 IDbContextFactory,因为我的一些控制器需要使用多个 DbContext 实例来获得正确的工作单元范围。

我也在尝试使用 xUnit 进行集成测试,但在将它用于内存数据库时遇到了困难。

这是我的 Startup 课程中的相关 sn-p

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContextFactory<ApplicationDbContext>(
                options => options.UseSqlServer("connection string")
            );

            //other services configured
        }

这就是 xUnit 应用程序工厂,它应该删除现有的 DbContextFactory 并将其替换为 InMemory 工厂。

public class TestApplicationFactory<TStartup>
        : WebApplicationFactory<TStartup> where TStartup: class
    {
        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            builder.ConfigureServices(services =>
            {
                var contextFactory = services.SingleOrDefault(
                    d => d.ServiceType ==
                        typeof(IDbContextFactory<ApplicationDbContext>)
                );
                services.Remove(contextFactory);
                
                services.AddDbContextFactory<ApplicationDbContext>(
                    options => options.UseInMemoryDatabase("InMemoryDbForTesting")
                );

                var sp = services.BuildServiceProvider();
                var dbf = sp.GetRequiredService<IDbContextFactory<ApplicationDbContext>>();
                var db = dbf.CreateDbContext();
                db.Database.EnsureCreated();

                // Pass the context to a class that will add seed data
                DbSeed.InitializeDbForTests(db);
            });
        }

当我逐步调试时,它似乎正在删除现有工厂,这可以从 services.Remove(contextFactory); 之后的服务计数下降中得到证明。行,它似乎也添加了新的,再次通过查看计数。

这不会引发任何错误,只是没有使用新的 DbContextFactory。

我在这里错过了什么?

提前感谢您的帮助。

【问题讨论】:

    标签: .net-core dependency-injection integration-testing xunit


    【解决方案1】:

    我发现了问题。

    Startup 类运行时

            public void ConfigureServices(IServiceCollection services)
            {
                services.AddDbContextFactory<ApplicationDbContext>(
                    options => options.UseSqlServer("connection string")
                );
    
                //other services configured
            }
    

    其实就是给服务集合添加四个描述符:

    1. IDbContextFactory\<ApplicationDbContext>
      
    2. IDbContextFactorySource\<ApplicationDbContext>
      
    3. DbContextOptions
      
    4. DbContextOptions\<ApplicationDbContext>
      

    解决方案是在 xUnit ApplicationFactory 中删除所有这些。我只删除了一个。删除其他三个后,我可以继续添加 DbContextFactory 的 InMemory 版本,它现在正确指向测试数据库。

    如果您有更高效或更优雅的解决方案,我很想知道。

    【讨论】:

      猜你喜欢
      • 2013-01-03
      • 1970-01-01
      • 2021-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-10
      • 2018-03-26
      相关资源
      最近更新 更多