如何确保按测试方法创建Entity Framework Core InMemory数据库?

时间:2019-04-30 17:07:58

标签: asp.net-core entity-framework-core integration-testing in-memory-database

亲爱的, 我正在尝试创建集成测试,以使用实体框架核心内存数据库提供程序来测试我的API控制器。 我创建了 CustomWebApplicationFactory ,用于根据official documentation guideline配置服务,包括数据库上下文 我在xunit测试类中将此工厂用作IClassFixture,但是当它们在 parallel 中运行时,我的测试被破坏了,因为我认为它们共享相同的数据库实例。 这是我的配置

protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            // Create a new service provider.
            var serviceProvider = new ServiceCollection()
                .AddEntityFrameworkInMemoryDatabase()
                .BuildServiceProvider();

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

            // Build the service provider.
            var sp = services.BuildServiceProvider();

            // Create a scope to obtain a reference to the database
            // context (ApplicationDbContext).
            using (var scope = sp.CreateScope())
            {
                var scopedServices = scope.ServiceProvider;
                var db = scopedServices.GetRequiredService<ApplicationDbContext>();


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


            }
        });
    }
}

1 个答案:

答案 0 :(得分:1)

  

我认为他们共享同一个数据库实例

您是正确的,IClassFixture是跨多个测试的共享对象实例。

重用ConfigureWebHost可以做的是改用测试类的构造函数。 这样,所有测试都将运行配置,但不会共享对象实例。您可能还需要更改options.UseInMemoryDatabase("InMemoryDbForTesting");以使用随机的内存数据库名称(例如options.UseInMemoryDatabase(Guid.NewGuid().ToString());

xunit官方文档也可能会帮助您:https://xunit.net/docs/shared-context