UNIT TESTING

End to End Unit Testing for .NET 6 Web API

A way of unit testing end to end the Web API in .NET 6

Nitesh Singhal
5 min readMar 28, 2022
Image by Nitesh Singhal

Dev 1: Why do we have low code coverage for .NET core Api project?

Dev 2: We have these classes such as program.cs and startup.cs which has lot of code that are not being covered during unit tests.

Dev 1 : Then write some tests for them and increase code coverage.

Dev 2 : It is not simple as it seems.

Dev 1: So what should we do ?

Dev 2 : Exclude them from code coverage.

Dev 1 : Ok.

Dev 2 : Done.

Dev 1: Great..! but what about logic that needs testing in those files ?

I am sure at point of time you must have had similar conversation with your Team or architect and probably you must have done the same.

so what can be done other then excluding them.

and for sure it is not about just coverage but also to test if things are correct.

With .NET 6, there is a way of writing Unit test little differently and test your API in a kind of end to end way rather then just writing unit test separately for each class.

you can call them however you like but to me it is way of testing API from end to end.

Let’s understand by example.

Project Setup

I have an API which returns a random activity when called.

swagger UI for API project

MyActivityController.cs

BackendService.cs

we have controller which call BackendService to get the activity from 3rd party API.

and now in typical old scenario we would only write the unit test for MyActivityController and BackendService separately to test the logic but program.cs class will not be tested and also tests for controller class would be kind of redundant as they would not be testing anything useful.

.NET 6 way of Testing

Let’s see how to solve this issue with .NET 6 tests.

Let’s start by creating a UnitTest project by executing following cmd

dotnet new nunit -o Activity.Api.Tests

and add the required references.

<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="NUnit" Version="3.13.2" /><PackageReference Include="NUnit3TestAdapter" Version="4.0.0" /><PackageReference Include="coverlet.msbuild" Version="3.1.0" />
<PackageReference Include="Moq" Version="4.17.2" />

add the project reference to activity.api project.

Project reference

we will also need one small change the Activity.Api.csproj file

Note: we need to add this to access program.cs in the test project.

Now we can write the unit tests.

First Unit test

Let’s execute the tests.

Unit test execution

THAT’S IT and we can see the test case is passed.

Let’s also check the coverage. I am using coverlet to collect the coverage

Code coverage

As we can see it has covered program.cs, controller and backend service

It says 50% branch coverage and still some % left for line coverage, it is because we have written only test for success scenario. to cover the maximum we have to write the code for other scenarios also.

Let’s write the test for negative scenario also.

[Test]
public async Task TestFailureReturnNull()
{
// Arrange
using var application = new WebApplicationFactory<Program>();
var client = application.CreateClient();
// Act
var responseMessage = await client.GetAsync("/MyActivity");
// Assert
Assert.AreEqual(HttpStatusCode.NoContent,responseMessage.StatusCode;
}

and on tests execution, I get following result

Unit test execution

It is failed because it is getting activity with Ok response but we expected to be NoContent. On further analysis, I found that we are depending on external API for getting the activity and during unit test we can’t control the result from external API.

so then we will have to mock the external dependency.

In my previous article I have explain how to mock http client.

Let’s make the change and test again.

first we will write a helper method to create the mock HttpClient.

Helper method for getting mock HttpClient

then we will write the test case

Unit test covers failure scenario

Let’s execute the tests.

Unit test execution

and we see that both tests are passing. Now let’s check the coverage.

Code Coverage

Now we see that everything is covered.

you can follow this article for setting up code coverage.

you can find the full source code at Github

Summary

In this tutorial, I have taken very basic example but in practical scenario there is much more code written in for configuring the services and all. and since we are able to write unit test for that we often get issue from that part of code.

using this technique we can test end to end. and also we have seen in the example that we can mock external dependencies as we can’t control them during unit test execution.

Hope it is helpful.

Happy coding and keep learning..!

--

--

Nitesh Singhal

Software architect, Exploring ASP.Net core and containerization technologies