How to ensure that Entity Framework Core InMemory database is created per test method?

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

Question

Dears, I am trying to create integration tests that tests my API controller using entity framework core in-memory database provider. I created CustomWebApplicationFactory that configure my services, including my db context according to official documentation guideline and I used this factory as IClassFixture in my xunit test classes but my tests got broken when they run in parallel because as i think they shared the same database instance. This is my configuration

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
4/30/2019 5:07:57 PM

Accepted Answer

i think they shared the same database instance

You are correct, IClassFixture is a shared object instance across multiple tests.

What you can do to reuse the ConfigureWebHost is use the test class' constructor instead. That way, all your tests will run the configuration but will not share object instances. You might also need to change the options.UseInMemoryDatabase("InMemoryDbForTesting"); to use a random in-memory db name (e.g. options.UseInMemoryDatabase(Guid.NewGuid().ToString());.

The official xunit docs might also help : https://xunit.net/docs/shared-context

1
4/30/2019 5:31:41 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow