I have a ASP.NET Core 2.2 WebApi project which uses also EF Core 2.2. The project is tested via integration tests with WebApplicationFactory<T>
.
I tried to migrate the the web api project to netcore/aspnetcore 3 which worked out very well. What I've stumbled across is migrating the tests.
I have following code which worked in aspnetcore 2.2:
public class MyServiceWebHostFactory : WebApplicationFactory<Service.Startup>
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
services.AddDbContext<MyContext>((options, context) =>
{
context.UseInMemoryDatabase("MyDb")
.UseInternalServiceProvider(serviceProvider);
});
var sp = services.BuildServiceProvider();
using var scope = sp.CreateScope();
var scopedServices = scope.ServiceProvider;
// try to receive context with inmemory provider:
var db = scopedServices.GetRequiredService<MyContext>();
// more code...
// Ensure the database is created.
//db.Database.EnsureCreated();
// more code...
});
}
}
It replaces the EF Core DbContext with a DbContext using the InMemoryProvider.
After migrating to 3.0 it isn't replaced anymore. I always receive the DBContext with SQL Server configured.
If I remove the services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString))
call in ConfigureServices
of the application (Service.Startup
) it works but this isn't a solution.
I also tried a services.RemoveAll(typeof(MyContext))
before registering the inmemory context which doesn't work either.
When the controller is being disposed, call dispose on your repository and that should dispose the context. If you are using a service layer and not talking to the repository directly from the controller, then call dispose on the service which will call dispose on repo which will dispose the context.
WebApplicationFactory provides multiple ways to customise your application in integration tests, but at it's core, it provides a way to run your application's Host instance in memory.
"More than one DbContext was found. Specify which one to use. Use the '-Context' parameter for PowerShell commands and the '--context' parameter for dotnet commands."
Popular Answer. DbContext should not be used as a singleton because it is holding a connection object which cannot be used by multiple threads at the same time. You will run into errors if two requests try to use it at the same time. If your service depends on the context, the service cannot be a singleton.
The updated documentation at https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-3.1 might be able to help. Key fragment change is to remove the previous context service registration:
// Remove the app's ApplicationDbContext registration.
var descriptor = services.SingleOrDefault(
d => d.ServiceType ==
typeof(DbContextOptions<ApplicationDbContext>));
if (descriptor != null)
{
services.Remove(descriptor);
}
// Add ApplicationDbContext using an in-memory database for testing.
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
});
// Build the service provider.
var sp = services.BuildServiceProvider();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With