Unit testing application layer in .NET Core
Unit testing the application layer of a .NET Core API based around the CA design approach
Unit testing the Application layer
Previously we have covered the use and value of unit tests when it comes to the domain layer. When speaking about the Application layer my personal preference is to use Integration Testing…. That said:
A very much valid practice is to unit test the standalone components of the Application layer.
We will piggy-back on the setup from the previous newsletter and add unit tests for a ValidationBehavior component.
If you are unfamiliar with how behaviors work in MediatR the closest example is the Middleware/Filter pipelines or Decorator pattern, it is really similar in nature. They let you to add logic before and after your Command or Query handlers execute.
I’ve seen people throw exceptions from the behaviors they write. I prefer introducing an artificial constraint and use the Result pattern instead and keep exceptions for exceptional cases only.
FluentResults is an excelent library to get started with using Results, and the one I’m going to use in this demo.
I will introduce an artificial constraint to make sure that all the commands and queries in the project will return either a Result or Result<T>. The easiest way to do that is like this:
Effectively all the commands/queries in the project will inherit from one of these interfaces.
In order to let our unit tests access the internal classes of another class library we will need to add an InternalVisibleTo setup to the .csproj. Generally it should look like this :
With all of that in place let’s take a look at the ValidationBehavior we will be using :
This is a simple PoC implementation where we validate the request and if the validation failed return a Result.Fail with the list of errors inside.
Building on top of the stuff we covered last week we can now unit test the behavior of the Handle method from the behavior. They might look like this :
In order to get more deterministic results we will have to mock out the validator for the command. For that we will use my preferred mocking library which is NSubstitute.
The result of the snapshot at the end will look like this:
Also we will need to cover the behavior in case no validation failures occurred. A simple test like this can check that :
The last test would be one that checks that the handler is invoked even if there is no validator defined for the specific command/query, but in order to keep the newsletter short I’ll leave that one as homework for you ;-)
As a final thought, while yes we can and should write unit tests for the standalone components from our Application Layer, I prefer much more testing this layer via Integration tests. So in the next part I’ll show you my preferred way of doing that.
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 :-)








