Introduction

Hey all ! ๐Ÿซก

Let’s talk about another little drama that has been shaking the .NET community during the last weeks.
When working on unit tests in .NET, developers often rely on assertion libraries to make their tests more readable and expressive.
Two popular libraries in this space are FluentAssertions and Shouldly. While both libraries serve the same purpose, one of them actually updated its licensing model and frightened the whole community about his new goal, making money ๐Ÿ˜‚ (Well who does not want to)
And this one is FluentAssertions.
In fact, it now requires a paid licence to be used for commercial use. At least, concerning the 8.x.x version. The developers have stated that the 7.x.x version will be forever free and receive critical fixes, but this strange move from their side may have pushed you to find another library for your assertions, to avoid any problems with the company you work for.
If that’s the case, here is a little tutorial that explains how to migrate from FluentAssertions to Shouldly !

Migration Steps

1. Install Shouldly

First, you need to add Shouldly to your project. You can do this using NuGet Package Manager or the .NET CLI.

dotnet add package Shouldly

or add it as a reference in your .csproj directly.

2. Replace FluentAssertions Usages

The core of the migration involves replacing FluentAssertions syntax with its equivalent in Shouldly, and updating namespaces. We will not cover each and every assertion scenario in this post, but the idea is to give you a sneekpeek of the syntax and how to migrate the most common scenarios ๐Ÿ˜‰
Below are some common assertions and their corresponding syntax transformations.
Use it to replace your FluentAssertion usages in your unit / integration tests codebase ๐Ÿ˜Ž

Feature FluentAssertions Syntax Shouldly Syntax
Equality Assertion actual.Should().Be(expected); actual.ShouldBe(expected);
Null Check actual.Should().BeNull(); actual.ShouldBeNull();
Not Null Check actual.Should().NotBeNull(); actual.ShouldNotBeNull();
Collection Contains collection.Should().Contain(item); collection.ShouldContain(item);
Collection Does Not Contain collection.Should().NotContain(item); collection.ShouldNotContain(item);
Greater Than actual.Should().BeGreaterThan(value); actual.ShouldBeGreaterThan(value);
Less Than actual.Should().BeLessThan(value); actual.ShouldBeLessThan(value);
Exception Assertion Action.Should().Throw<Exception>(); Should.Throw<Exception>(Action);
No Exception Assertion Action.Should().NotThrow(); Should.NotThrow(Action);
Async Exception Assertion await Action.Should().ThrowAsync<Exception>(); await Should.ThrowAsync<Exception>(Action);
No Async Exception Assertion await Action.Should().NotThrowAsync(); await Should.NotThrowAsync(Action);

Additional tips for a smooth migration ๐Ÿ„โ€โ™€๏ธ

  • Automate syntax replacement: If your codebase contains a large number of tests, consider writing a script or using a tool to automate the replacement of FluentAssertions syntax with Shouldly.
  • Migrate incrementally: Instead of migrating the entire codebase at once, tackle one test file or module at a time. This approach reduces the risk of introducing errors and makes it easier to track progress.
  • Collaborate with your team: Ensure that all team members are aware of the migration and understand the new syntax. This will help maintain consistency across the project.

Conclusion

Not that much changes right ? ๐Ÿ˜
Migrating from FluentAssertions to Shouldly is in fact a pretty straightforward process that involves replacing syntax, updating namespaces, and refactoring for readability.
It shouldn’t be that long to migrate even on a big project, considering you could also automatize the whole process using custom scripts.
Shouldlyโ€™s more natural language style and detailed error messages can significantly enhance the clarity and maintainability in tests, and is completely open source, so take it in consideration as a good alternative !

Happy hacking ๐Ÿ‘จโ€๐Ÿ’ปโค๏ธ