In this post, I want to explain how to set up integration tests in .NET 6. I want to use the TestServer feature with an in-memory EF database to check if my API works correctly.
Prerequisites
As a prerequisite, you should have the API project created. I’m using the WebAPI project using the Clean Architecture approach.
Add xUnit test project
Firstly, let’s create the test project. I will be using xUnit as it has a nice feature of injecting services into the Tests. I will use this feature to inject our startup class into the test class.
You can create the xUnit Test project using the .NET CLI:
Setup in memory web server with TestServer
Update Program.cs
Integration Tests, which I will set up, will be using an in-memory web server. This means I don’t need to deploy the web app to the server to do integration testing.
I will use the TestServer instance and invoke HttpClient from it, calling endpoints to test them.
In the .NET 6, it was introduced a new approach of starting the application with a much smaller and cleaner Program.cs. If you have created a new .NET 6 application,
your Program.cs file should look like this:
The first thing is to add the lines below to the end of the Program.cs file. There is no explicitly created Program class, so that we will do this by the end of the file.
Create IntegrationTestsFactory
Next, I need to create a factory, which later be injected into our class as a dependency.
You can see that I’m switching to another environment. I’m using the “Test” environment. I’ve created a new configuration file only for integration testing, which will read from the appsettings.test.json file. Then you see that I’m injecting the Tests configuration - like user’s data or other data in the InitIntegrationTestsConfiguration method.
Lastly, I’m changing the implementation of some services. I’m switching from the standard database connection to the in-memory database and from JWT Token implementation to FakeJwtToken.
Having that, I’m ready to start writing the first integration test.
Notice, we can do much more in the factory here. We can, e.g., seed the database with example data.
Prepare Test class and first tests
Prepare TestBase class
The next thing to do is prepare the TestBase class, which will prepare the HttpClient and configure e.g., the FakeJwtToken or prepare the database. Let’s see it:
Having that we are ready to create first integration tests.
Prepare firsts integrarion test
As you see, in the Act(), I prepare which endpoint we will be testing. Later I arrange the database using the method from TestBaseClass.
I decided to create this method in TestBase class, not to forget to save changes in every test class. With that approach, I only need to
remember about setting up the database correctly before the test.
Then I’m acting and checking what the mocked server response is. It should be equivalent to the state I arranged before the test.