Verify data in tests with ASP.NET Core and EF Core in memory


You’re writing a Web API with ASP.NET Core 2.1, and use EF Core as your ORM.
If you follow the official guidance on doing integration tests in ASP.NET Core 2.1, then you can use either an in-memory database provider, or SQLite in-memory. We are using an in-memory database provider, which is setup in our CustomWebApplicationFactory as per the current Microsoft guidelines which are these:

public class CustomWebApplicationFactory<TStartup> 
    : WebApplicationFactory<RazorPagesProject.Startup>
    protected override void ConfigureWebHost(IWebHostBuilder builder)
        builder.ConfigureServices(services =>
            // Create a new service provider.
            var serviceProvider = new ServiceCollection()

            // Add a database context (ApplicationDbContext) using an in-memory 
            // database for testing.
            services.AddDbContext<ApplicationDbContext>(options => 

These work well when running integration tests, as it allows you to quickly setup a database for each test, independent of every other test.

The problem

I couldn’t find any guidance on how to verify the data gets written correctly to the database in an assertion. e.g. here is one of our tests. We are using the XBehave library:

public void CreateApplication_ShouldReturn201()
    "Given a valid create application request"
      .x(() => _fixture.GivenAValidCreateApplicationRequest());
    "When an application is created"
      .x(() => _fixture.WhenAnApplicationIsCreated());
    "Then the response http status code is a 201"
      .x(() => _fixture.ThenTheResponseStatusCodeIs(HttpStatusCode.Created));
    "And the response should contain an id"
      .x(() => _fixture.ThenTheResponseShouldContainAnApplicationId());
    "And the database should contain the application"
      .x(() => _fixture.ThenTheDatabaseShouldContainTheApplication());

How to verify the final step – “ThenTheDatabaseShouldContainTheApplication”?

The solution

Firstly, you need to change the call to AddDbContext so that your DbContext is a Singleton (the default is Scoped).

services.AddDbContext<ApplicationDbContext>(options => 
}, ServiceLifetime.Singleton);

Then, you can get a DbContext from the system under test by asking its service collection for one, with a helper property like so:

protected ApplicationDbContext DbContext
    get => TestServer.Host.Services.GetService(typeof(ApplicationDbContext)) as ApplicationDbContext;

Since the DbContext is a singleton it’ll be the same one the system under test used, so we can query the DbContext for it directly.

internal void ThenTheDatabaseShouldContainTheApplication()
    var application = DbContext.Applications.Find(ApplicationId);

8 thoughts on “Verify data in tests with ASP.NET Core and EF Core in memory

    • Hi Anton. It’s been a few months since I blogged this, but I think you can leave you application code using a Scoped DbContext (the default). The code above where I tell it to use a Singleton is in my test code – the application code is unchanged – i.e. here’s the line from my Startup.cs:

      services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString));

    • For my tests that behaviour is desired, since it means each test has a clean database without needing to worry about database teardown. But I have noticed some alarming memory usage when running around 300 tests, so maybe I need to revisit that design.

  1. Do you have a repository with the full code? My context is null, although I can access it to seed the database during ConfigureWebHost.

  2. Having trouble with this since 3.0. Now you have to access the services through a different means. Can you take a look at this?


    System.InvalidOperationException : Cannot resolve scoped service ‘WebApplication.Model.ApplicationDbContext’ from root provider.
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type serviceType, IServiceScope scope, IServiceScope rootScope)
    at Microsoft.Extensions.DependencyInjection.ServiceProvider.Microsoft.Extensions.DependencyInjection.ServiceLookup.IServiceProviderEngineCallback.OnResolve(Type serviceType, IServiceScope scope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
    at TestProject2.UnitTest1..ctor(CustomWebApplicationFactory`1 factory) in C:\Users\xxxxxxxxx\RiderProjects\WebApplication\TestProject2\UnitTest1.cs:line 19

    You now have to get the services like so:

    _db = factory.Services.GetService(typeof(ApplicationDbContext)) as

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s