Testing around databases
When developing back-end systems and Web APIs, it's pretty common that the code will need to interact with a database, including targeting the database, connecting to its server, performing SQL queries, and running commands or T-SQL scripts.
Historically, databases have been one of the main ledgers in most systems, and several implementations have been developed to interact with a database in a flexible way.
Use Entity Framework Core's built-in testability
With the introduction of Entity Framework, and more recently Entity Framework Core, you can build integration tests in a way that allows your application to communicate with the database ledger in your system without the need to be configured and provisioned.
One of the benefits of Entity Framework is the in-memory database option that can be started and removed in each test. An in-memory database can be seeded with data as needed to deal with the database component in your system, so it can be easily configured to run in the context that best fits your needs.
In-memory database support
Dealing with a database is not easy from a testing perspective. In addition to programming it, there are the administration and maintenance tasks that come with its lifecycle and growth over time.
For unit and integration tests, you don't necessarily need to deal with a real database on a server. Alternatively, Entity Framework Core comes with some level of support for in-memory databases, which makes your code perform closer to how a real database performs, all inside your test context and within reach of your test host.
To enable the in-memory support for your code, you can have Microsoft.EntityFrameworkCore.InMemory installed in your integration test project and make it work with your existing EntityFramework Code:
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.0.2" />
To create an instance of a DbContext to use for our tests, and assuming we are testing something using the Database context named ApplicationDbContext:
Open the ApplicationDbContext.cs file and make sure you have a constructor that lets you set up the context with context options. If you do not have this constructor, add the following code to the ApplicationDbContext.cs file:
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options): base(options){}
Set up the existing database context to use in-memory database. This example does this inside a single test case. For a test class that runs many tests against the same service or repository, you can set up the context in a constructor for the
test
class and reuse between tests.
[Fact]
public async Task Test1()
{
bool expected=true;
bool actual;
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: "Add_writes_to_database")
.Options;
SomeExampleService service = null;
// Run the test against one instance of the context
using (var context = new ApplicationDbContext(options))
{
service = new PaymentReceiptsService(new PaymentReceiptsRepository(context));
actual = service.SomeMethod();
}
Assert.True(expected==actual);
}
Let's recap!
Entity Framework Core provides a built-in support for developing Web APIs with testing in mind. You can use the in-memory support package to configure and use a dedicated database instance in memory for your testing needs without having to worry about the provisioning, maintenance, and availability of a database server.