Integration testing in .NET Core
Running integration tests for your Application Layer.
— Unit tests are small, fast automated tests that validate specific behaviours of your code in isolation from dependencies.
— Integration tests will focus on evaluating how the solution and it’s dependencies works as a whole.
Personally, I trust integration testing more than unit testing for a simple reason: it provides a more realistic representation.
Let's imagine you have a car. Every component of the car has been tested in isolation, but no test has been performed after the car has been assembled. Would you feel comfortable driving it? I would not.
However, this does not mean that unit tests are inferior or superior to integration tests. They simply serve different purposes and have distinct areas of focus.
Quick disclaimer there are essentially 2 levels at which you can run the integration tests:
API level
Subcutaneous level
In this week’s post we will cover the first one, leaving room for the following post.
In our case we are going to run integration tests against the routing/presentation layer of our system while also wiring up the infrastructure with a MongoDb instance.
Behind the scene I have added a couple of API endpoints for basic CRUD operations, create / read / delete.
To start off we will have to create a separate Integration tests project in our solution. Just like in the first chapter of the series for the unit tests. This is the setup how it would look like
To run our API level integration tests we would need to set up an instance of the API. Using the
Microsoft.AspnetCore.Mvc.TestingNuGet package we can easily run an instance of our API in memory.In order to validate the behavior we will need to have an instance of MongoDb running on demand during our tests. For that we will use
Testcontainers.MongoDband spin up a new instance of database.
The setup code for that would look like this:
This ApiFactory will help us spin up an instance of our API in memory and also create HTTP clients to call the said instance.
The WebApplicationFactory expects us to provide it with a type that serves as the "EntryPoint" for our web application. In simpler terms, it is a marker that indicates the web project assembly.
While many people use the Program.cs file as the marker for the WebApplicationFactory, I prefer setting up a separate marker interface within the web project. This provides more flexibility and clarity.
Now let’s write some tests. We already covered a bit the AAA (arrange, act, assert) approach to writing tests in our Unit tests post. Since setting up a new API and database for every test(method) would be a waste let’s use the IClassFixture construct from xUnit.
This will allow us to spin up a single instance of our API per test class and run our tests against it.
Since all the tests in a test class run sequentially we shouldn’t run into concurrency issues between the tests. A simple PoC test to validate that a card game was created then stored in the database would look like this:
Now there are a set of things to mention here:
Creating a new HTTP client for each test is also wasteful so we will create it once (see constructor) and reuse it.
There is going to be a single instance of our API and Database running for the entire test class using the IClassFixture.
Since we are reusing the database across all tests in a test class we will have to take care of the cleanup. A really simple approach is to store the codes of the entities we create and then at the end of the test in DisposeAsync call the delete api endpoint.
Adding other types of tests like validation etc I’ll leave that as homework for you all.
Combining the Routing + Application + Infrastructure like this is really easy and can increase the overall confidence that your application is doing what is was designed to.
Maybe even to the point that you won’t be afraid to deploy on Fridays :P .
If you liked this kind of content/tutorial I will be really grateful if you cloud share it among your colleagues and friends in order to grow the newsletter further.
Heads up:
I just release an entire course around the topic of building a Modular Monolith system that you can find clicking here : Microservices Ready Architecture
Become a Patreon and get access to the source code presented in the newsletters and YouTube channel.
And with that cya next time :-)






