In my previous blog post I showed you how to test the public API of a microservice that is secured by Auth0. In this follow on post I want to demonstrate another technique which makes use of a neat little library maintained by Dominique St. Amand that allows us to use fake tokens in our tests. The library was originally developed by GestionSystemesTelecom. Using this technique we do not need to use secrets at all and thus can avoid the risk of potentially leaking those secrets.
The code to accompanying this post can be found on GitHub.
Scaffolding the Test Project
I am going to assume that you have read the previous post in this series and created the code samples (if not, please do this now here, we wait…).
Now we are going to add another .NET Core test project using the xUnit template.
- Navigate to your solution folder:
$ cd ~/glossary
- Create the test project:
$ dotnet new xunit --output tests-with-fake-tokens
- Add the awesome FluentAssertions NuGet package to the project. It will help us making our assertions look or read more naturally:
$ dotnet add tests-with-fake-tokens package FluentAssertions
- Now the most important part, add the NuGet package:
$ dotnet add tests-with-fake-tokens package WebMotions.Fake.Authentication.JwtBearer
make sure you install version3.0.1
or newer (as version3.0.0
contains a bug) - Finally add the Microsoft Testing library:
$ dotnet add tests-with-fake-tokens package Microsoft.AspNetCore.Mvc.Testing
With that we are ready to write some infrastructure code to make our tests less verbose.
- Delete the file
UnitTests1.cs
from the project - Add a new file called
WebApiTestFactory.cs
to the project and add the following code to it:
This class inherits from the WebApplicationFactory<TStartup>
provided by the Microsoft Microsoft.AspNetCore.Mvc.Testing
NuGet package. It uses our Startup
class from the api
project and overrides some of its configuration settings. Mainly the part for authentication on line 26 through 30. We can see that it uses our fake JWT Bearer token library instead of what we asked for in the Startup.cs
class, where we define Auth0 as our identity provider.
- Add a file called
ControllerTestsBase.cs
to the project with the following content:
This class will be used as base class for all our test suites we are going to write. This base class uses the injected factory object (defined in step 2) to create a test HTTP client for use in our tests and also prepares a fake token that we will use in the tests to pass as part of the Authentication header in calls to secured endpoints.
This is all we need in our scaffolding.
Writing Tests
Now let’s write our first test.
- Add a file called
GlossaryControllerTests.cs
to the test project - To the above file add the following code:
In our first test we do not need a Bearer token since the /api/glossary [GET]
endpoint is not protected. We use the client object to do a async GET to that endpoint on line 21. Then we use the fluent assertion style provided to us by the FluentAssertions
NuGet package on line 23, 26 and 27 to verify the outcome of the request.
Also note how the class inherits from our base class.
- In your terminal window, from within the solution folder run the tests:
$ dotnet watch -p tests-with-fake-tokens test
Make sure the test run is successful - Now let’s add a second test that probes the endpoint
/api/glossary/accesstoken
:
The code should be straight forward at this time. Notice that this endpoint too doesn’t need a token since it is not secured.
The tests should rerun automatically once you save your changes. Make sure you have 2 passing tests.
- Let’s now verify that when accessing the protected DELETE endpoint we get the correct authorization error. Add this code to the test suite;
Make sure the tests rerun and are all successful after you save your changes
- Please add similar tests for the POST and PUT endpoints of the glossary controller
- Now let’s write a test that creates a new glossary item and uses a fake token to get authorized. Add the following code to the test suite:
Notice how in the above test on line 4 we use the extension method SetFakeBearerToken
defined in the WebMotions.Fake.Authentication.JwtBearer
library to define a Authorization request header that will make this test pass although the called endpoint is protected.
Please find more tests in the source code here.
Production pushes fail because of one skipped step. Add an Automated Smoke Test as that missing step. This will flush out bugs, site degradation, and unexpected interdependencies.
Conclusion
In this post I have presented a possible way to write integration tests against .NET Core Web API controllers that are protected with the [authorize]
attribute. We are using the library provided in the WebMotions.Fake.Authentication.JwtBearer
NuGet package in combination with the Microsoft test web host to simulate successful authentication whilst providing “only” a fake Bearer token. This method is an alternative to the one presented in the previous post that used secrets to access the admin API of Auth0 to procure a valid token used in the tests. The advantage of the former in comparison with the latter is that we do not need to use any secrets and thus eliminate the risk that those secrets could leak.
The code accompanying this post can be found on GitHub.
ABOUT THE AUTHOR
Gabriel is the Lead Solution Architect at TechGroup. He’s a Docker and Apache Kafka expert and has many years of experience in the area of highly distributed, mission critical enterprise applications. Gabriel is the author of several books and articles, as well as of 2 video series about Docker Containers and Kubernetes and about Angular JS. In his spare time Gabriel is a passionate cook and loves to hike in the mountains and dive in the deep sea. Follow him on Twitter at @gnschenker or read his blog at https://gabrielschenker.com/index.php/blog/