ASP.NET Core 2+ best practices and practical tools for testing, part 1

ASP.NET Core 2+ best practices and practical tools for testing, part 1

Introduction

When developing an application, two big questions are coming:

  • How can we know and verify if an implementation remains compliant with the expected operating rule, preventing regressions in case of evolution of the program ?
  • How can we know and verify if the behavior of each software layer between them ?

The answers are definitely: Make unit and integration tests!

But how can we achieve that?

This article will describe the best practices and the practical tools that can be used to make efficient unit and integration tests.

Philosophy and good practices of unit tests

  • The class tested (SUT) in complete isolation
    • Some exceptions are allowed (mock files)
  • The test must be easy to write, if not, refactor!
  • The test must run quickly
    • Some exceptions are allowed especially when your business logic has complex computation
  • The test must easy to understand
    • Respect coding conventions
    • Normalize tests name to understand what is does
    • Don’t hesitate to use nested classes to group your tests on the same SUT
    • Identify clearly each step (Arrange, Act, Assert)
  • Test only one behavior
    • But testing one behavior doesn’t one Assert!
  • Don’t try to test at 100% your code
    • It’s unefficient
    • It’s very expensive

Philosophy and good practices of integration tests

  • Have to run them after unit tests
    • It’s better to test first if each component works by itself before checking that it integrates with others
  • Ideally make an end-to-end test instead of testing a service and a repository
    • It’s more efficient and there is less code to write

Practical tools for testing

xUnit is a test execution tool, the most used and supported by the community: https://xunit.net/

NSubstitute is a mocking library, very popular and very easy to use: https://nsubstitute.github.io/

FluentAssertion is an assertion library, popular. Makes easier to understand the intent of your tests: https://fluentassertions.com/

AutoFixture is a practical variables setup tool, minimize the time spent to arrange a test. Gain in readability and maintainability: https://github.com/AutoFixture/AutoFixture

ExpectedObjects Allows to compare objects by their value (not their reference). No need anymore to test each property. Gain in readability and maintainability: https://github.com/derekgreer/expectedObjects

JsonSerializer, very usefull in certain cases to generate data: https://www.newtonsoft.com/json

TestServer is a test web host and an in-memory test server. It’s an easy way to make end-to-end tests: https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2

FakeJwt is simply the Microsoft.AspNetCore.Authentication.JwtBearer assembly rewritten with fake validation. Originally rewritten by “GestionSystemesTelecom” company here: https://github.com/GestionSystemesTelecom/fake-authentication-jwtbearer, I had to modify it to make it compatible with ASP.NET Core 2.2. It can be downloaded here: https://github.com/AnthonyGiretti/commonfeatures-webapi-aspnetcore/tree/master/GST.Fake.Authentication.JwtBearer. It allows to use fake JWT for integration tests, no need to use a real JWT configuration to run your integration tests. *

* Some examples of use have already been written by Dominique Saint-Amand here: https://www.domstamand.com/testing-a-webapi-in-net-core-with-integration-tests/.

In the part 2 I will provide other examples.