
This post covers the basic structure for unit tests with Entity Framework Core.
Note: Unit tests are only there to test the respective logic. Unit tests do not replace integration tests, especially for database operations.
Install EFCore In-Memory Provider
EFCore comes with its own InMemory Provider, which is explicitly intended for testing and not for production: Microsoft.EntityFrameworkCore.InMemory
Conveniently, NuGet offers the possibility to simply copy the necessary package reference as an XML entry in order to paste it directly into the project file:
1<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.0" />
Setup Test Database Context
The goal is that each test has its own virtual, In-Memory database to enable real isolation in the tests.
I simply use a Guid, which acts as database name. This means that each test can run in parallel, as each test gets its own database and thus its isolated infrastructure.
1
2// Setup Options
3string dbName = Guid.NewGuid().ToString();
4DbContextOptions<MyDbContext> options = new DbContextOptionsBuilder<MyDbContext>()
5 .UseInMemoryDatabase(databaseName: dbName).Options;
The database options can now be used in a test to build the respective context.
1 using (MyDbContext dbContext = new MyDbContext(options))
2 {
3 // your database stuff
4 }
Sample Test
It is generally recommended that adding and querying values in tests be done in different contexts.
Here is a complete example of an EF Core Test
- Connection establishment
- Adding values
- Querying values
1[Fact]
2public async Task User_Should_Be_Added()
3{
4 // Setup
5 string dbName = Guid.NewGuid().ToString();
6 DbContextOptions<MyDbContext> options = new DbContextOptionsBuilder<MyDbContext>()
7 .UseInMemoryDatabase(databaseName: dbName).Options;
8
9 // Seed
10 using (MyDbContext dbContext = new MyDbContext(options))
11 {
12 PersonEntity person = PersonEntity.Create(1, "Batman", "Gotham City");
13
14 await dbContext.Persons.AddAsync(person);
15 await dbContext.SaveChangesAsync();
16 }
17
18 // Verify if insert works
19 using (MyDbContext dbContext = new MyDbContext(options))
20 {
21 PersonEntity person = await dbContext.Persons.SingleAsync(x => x.Id == 1);
22
23 // verify reference
24 person.Should().NotBe(null);
25
26 // verify properties
27 person.Id.Should().Be(1);
28 person.Name.Should().Be("Batman");
29 person.City.Should().Be("Gotham City");
30 }
31}
In the case of a repository test, this code could be used almost 1:1.
Better Testing
For easier, better tests I recommend using the following libraries:
- XUnit - Test Framework
- FluentAssertions
- Extension Methods for naturally assertions (like
.Should()methods) - Moq - Best .NET mocking framework
- AutoFixture - injects values to test methods
- AutoFixture.AutoMoq - injects mocks to test methods
- AutoFixture.Xunit2 - Extensions for XUnit
- AutoFixture.SeedExtensions - great extensions for specific autofixture operations

Comments