Skip to main content

Unit Test Assertions on steroids - with Fluent Assertions

Unit testing has long been a key part of the software development life cycle, ensuring good quality of product and faster time to market. Adding them to our DevOps pipeline enables us to run unit tests in a consistent manner, based on a specified trigger. This allows us to detect errors in our code, early on in the process and prevents breaking of existing functionality in the future.

All this sounds great, but imagine few months or years down the line, when some of the unit tests
fail - will we be able to accurately assess the reason for the failure, and do so in a short period of time, so as to avoid any delays to our project release schedule. It's important to have clear and precise failure messages to help debug and fix the issues faster.

The assert failure messages that most of the frameworks like NUnit or XUnit generate, are not easy to understand and might take developers a while to decode. Below is one such example.

Expected : 12
But was : 11

A developer reading this message might have to go back to the unit test or the system under test (SUT) in order to make some sense of it. This becomes even more difficult in huge enterprise-based applications with thousands of unit tests.

Fluent assertions is one such library that can help us address the issues already discussed. It not only makes it easy for developers to write assertions, but also increases the readability of the failure messages. Below is a test failure message with Fluent assertions.

Expected totalMonths to be 12, but found 11.

Note that totalMonths is variable, of which we are trying to assert the value. That's why it's also important to have well-defined variables names.

What is Fluent assertion? 
According to the fluent assertion Team
A very extensive set of extension methods that allow you to more naturally specify the expected outcome of a TDD or BDD-style unit tests.
Fluent assertions works with majority of the testing frameworks such as MSTest, MSTest2, Gallio, NUnit, XUnit, MBunit etc. In order to get started - we just have to add the Fluent Assertions NuGet package to our unit test project. This can either be done by right-clicking on the project and clicking "Manage NuGet Packages..." (in visual studio) or by running the below command using the package manager console window.

Install-Package FluentAssertions

As already mentioned, one of things that Fluent assertions can help with, is to increase the readability of the assert statements. Below you can see the difference between the MSTest assert and Fluent assertions assert
There are several extensions methods available out of the box. Obviously, I wont be able to discuss all of them here, but below are a few examples. Head over to the Fluent assertion documentation site to find out more.
There are also extensions specific to various datatypes. In case of collections the whole list of items are printed out along with the failure messages, so that it's easier to debug.

We can also chain severals assertions in one single command

Some of the unit tests that we write can have several assertions, when a failure occurs in one of the assertions the code execution terminates, and rest of the assertions will not be evaluated. This can lead to a lot of back and forth of debugging and fixing, in case of multiple failures. In order to address this, we can place all assertions into an AssertionScope(), which will throw one exception at the end of the scope with all failures.
Even the structural integrity of the code can be tested using Fluent assertions extension methods, by verifying the Types, Methods, Properties or Assembly References.
Fundamentally, this is what Fluent assertion is, a bunch of extension methods that make it easy to write and read assert statements, as it's represented more as a sentence, rather than an assert statement.