Improving Unit Testing with FluentAssertions

09 April 2021 at 02:00 by ParTech Media - Post a comment

Let us revisit the basics. A unit is the smallest part of a program that is logically independent. In most programming languages a function is referred to as a unit. And unit testing is the process of testing that unit in a program. Any test that involves external systems like a connection to a database or the one that relies on any other function is not unit testing.

Unit testing is quite an important part of any development project. It helps in identifying the bugs even before the integration is carried out saving precious time for the developers. Unfortunately, unit testing takes a lot of time and can often lead to poor results.

To prevent that, we have FluentAssertions. In this post, let us find out what is Fluent Assertions and how it helps to improve unit testing.

Table of contents

  • Why Unit Testing?
  • What is FluentAssertions?
  • Scope of Assertions
  • Commonly used Asserts
  • Asserts with JSON
  • How does the usage of FluentAssertions improve unit testing?
  • Conclusion

Why Unit Testing?

The final stage of software testing is usually Unit Testing. This is typically done before the software gets deployed. In this stage, each logically independent snippet of code is tested to check if these pieces of code give the desired result. These snippets are usually expected to have a single output. Unit testing is usually done during the coding phase so as to make the software free of bugs before it gets deployed.

Here are some of the reasons why we do unit testing -

  • The agility of the code is improved.
  • The risk of refactoring the code i.e., changing the code is reduced.
  • It improves the quality of code by exposing the edge cases which results in better results.
  • It helps in identifying the bugs in the code before the integration testing is carried out, thereby making the process of debugging easier.
  • The design and the structure of the code are improved as the programmer needs to think through what a method needs to accomplish.

What is FluentAssertions?

FluentAssertions is a bunch of .NET extension methods. It allows you to specify the expected outcome of a Test-driven development or Behavior-driven development unit test. You can enable it by using the below syntax -

using FluentAssertions;

FluentAssertions supports most of the unit testing frameworks. All you have to do is add a reference to the desired test framework assembly to the unit test project. The corresponding assembly will be automatically found by FluentAssertions and use to throw framework-specific exceptions.

The FluentAssertions library gives better support for exceptions and increases the readability of the tests while making it easier to generate unit tests.

Following is an example of a simple assertion:

The value of “a” is initialized with 10 and adding another 10 to it makes the value 20. So our test with FluentAssertions is done using the code a.Should().Be(20) which is more readable than Assert.AreEqual(a,20).

The different platforms that support unit testing using FluentAssertions are -

  • Xamarin.iOS 10.0
  • .Net Core 1.0
  • Xamarin.Mac 3.0
  • .Net Core 2.0
  • Xamarin.Android 7.0
  • Mono
  • Universal Windows Platform
  • .Net Framework 4.5

The different frameworks that support unit testing using FluentAssertions are -

  • MSTest (Visual Studio 2010, Vis
  • MBUnit
  • NUnit
  • XUnit
  • XUnit2
  • NSpec
  • MSpec
  • Gallio

Scope of Assertions

All the assertions can be batched into a single AssertionScope which will make the FluentAssertions throw a single exception at the end of the scope for all the failures inside the scope.

Commonly used Asserts

Here are some of the commonly used Asserts:

  • Strings (string theString=””;):

    • theString.Should().NotBeNull();
    • theString.Should().BeNull();
    • theString.Should().BeEmpty();
    • theString.Should().NotBeEmpty(“Can’t be empty”);
    • theString.Should().Be(“Some string”);
    • theString.Should().NotBe(“Some string”);
    • theString.Should().BeEquivalentTo(“Some string”);
    • theString.Should().NotBeEquivalentTo(“Some string”);
  • Numerical (int a=5;):

    • a.Should().BeGreaterOrEqualTo(5);
    • a.Should().BeGreaterThan(4);
    • a.Should().BeLessOrEqualTo(5);
    • a.Should().Be(5);
    • a.Should().NotBe(5);

Given below is the list of Assertions allowed in JSON:

  • BeEquivalentTo()
  • ContainSingleElement()
  • ContainSubtree()
  • HaveCount()
  • HaveElement()
  • HaveValue()
  • MatchRegex()
  • NotBeEquivalentTo()
  • NotHaveValue()
  • NotMatchRegex()
  • NotHaveElement()

Do not forget to use FluentAssertions.Json. If that’s not done, false positives may occur.

How does the usage of FluentAssertions improve unit testing?

Here is an example clearly captures the differences in understanding the code and writing it in an easier way when FluentAssertion is used for unit testing. Unlike normal unit testing, FluentAssertions gives following benefits which make its usage beneficial to the programmer while carrying out unit testing:

Improves Readability

In the above example, we can see that the same unit testing is done using Assert and FluentAssertions. And it can be clearly seen that the second unit test is easier to read in comparison to the first one.

Clearer explanation of the failure of the test

Snippet 1

Snippet 2

In the above two snippets, we can see that the difference between using Assert and FluentAssertions. In the second snippet, it is quite easy to understand why the test failed, thanks to a readable message. However, in the first one, we do not get a clear message.

Conclusion

As we have seen in this post, using FluentAssertions helps your unit testing activities significantly. It not only improves the readability but also clearly defines the failure of a test case. Both these benefits help the tester to easily course correct in case there is an error in the code. So use FluentAssertions in your next unit testing project to enjoy its multiple benefits.