Integration Test In Asp.Net Core 6 Using SqlServer Image and TestContainers

This post is about writing integration tests and TestContainers. As you might know writing integration tests against the in-memory provider is a bad practice. Because it only works well with trivial solutions. Mostly because the in-memory API of IQueryProvider doesn’t match the LINQ query provider. Here’s a good article called “Avoid In-Memory Databases for Tests” by Jimmy Bogard that goes into depth about this problem.

But what is a good solution if you want to integration test your, APIs that are backed by, let’s say SQL server database? One option is to create an actual database and manage the data creation and deletion for each integration test there. Even though that totally possible, it is rather a cumbersome solution. But there’s an easier solution to this that we’re going to discuss in this post. We can use docker containers to run an instance of SQL server for us as long as the test is running, and then delete the container when our tests are finished, and we no longer need it.

Setting up Asp.Net Core 6 Integration Test with TestContainers

The first step is to create our IntegrationTestFactory classing using what Asp.Net Core 6 provides to us. In this case we’re going to use the class WebApplicationFactory in Microsoft.AspNetCore.Mvc.Testing namespace. We’re going to inherit from this class and setup our webhost. This webhost is going to be responsible to basically run our integration tests against our API. We’ll set it up like so:

Here we first remove the previous DbContext from our DI injection graph and register a new one that points to the connection string that we’re going to create in our container.

Setting up the TestContainers with Sql Server Image

The next step is to create our test container. In order to have a reference to TestcontainerDatabase class, we need to install the Testcontainers package.

After Installing the package, we can setup our test container like so:

Here we use the TestcontainersBuilder and pass the type MsSqlTestcontainer as its generic argument. Then we’re going to create an instance of MsSqlTestcontainerConfiguration and in it we’re going to specify the password. In this case setting up the username and port and database name is not possible, if we set them, we’re going to receive NotImplementedException. Since we use Entity Framework Code First with SQL server, we’re going to use a SQL server image. This image (“mcr.microsoft.com/mssql/server:2022-latest“) is going to be pulled and run inside the docker container.

There are also two extra methods called InitializeAsync and DisposeAsync that is required to be implemented when we inherit from WebApplicationFactory. These two methods are going to be called whenever the app starts and ends. In the app start we’re going to start the container by calling _container.StartAsync(). When the app ends, we’re going to call _container.DisposeAsync().

The whole IntegrationTestFactory class is going to look something like this.

Creating IntegrationTestBase to ease the Integration test Creation

One extra step is to create a base class for all of our integration tests. In this class we’re going to create the things that we’re going to use often in our integration tests. More specifically in this class we’re going to create IntegrationTestFactory and our db context and make it available to our inheritors. Here’s all the code for this class.

Writing Some Integration Tests Using TestContainers

Now we can start writing some integration tests that will use the test containers to run a SQL server image inside docker. Here’s how the class and its constructor will look like.

Finally, here’s a test that we’ve written using the things we’ve created so far.

Here’s a picture of the images that are running inside the docker once we run our test.

If you want to experiment with this code and the tests you can clone CuratedArt repository and take a look. Don’t forget to install docker before running the tests.

Summary

In this post we saw how we can use TestContainers package to run our integration tests in docker using the latest SQL server 2022 image. If you want to check the codes mentioned in this post, you can visit CuratedArt repository and go to its integration tests project.

Share...
 

Hamid Mosalla

Hi, I'm Hamid Mosalla, I'm a software developer, indie cinema fan and a classical music aficionado. Here I write about my experiences mostly related to web development and .Net.

 

Leave a Reply

Your email address will not be published.