Skip to content
  • English Deutsch

benjamin-abt.com

Performance is a feature | Cloud - AI - Azure - .NET - Sustainability

  • Home
  • Blog
  • Portfolio
    • Overview
    • Workshops & Training
    • Publications
  • Contact
  • Home
  • Blog

Replace FluentAssertions with AI

Replace FluentAssertions with AI
January 15, 2025 5 min read BEN ABT
Csharp .NET Fluentassertions GitHub Copilot Chatgpt

New year - new .NET drama. You would have thought that positive lessons had been learned from the last Moq drama; but we were proven wrong.

What happened?

The owners of FluentAssertions have apparently decided to switch from a free open source license Apache 2.0 to a commercial license at short notice , without transparency or communication. And the whole thing has already been published with version 8. Earlier releases remain unaffected, as licenses, especially Apache 2.0, cannot be withdrawn across the board. The fact that all pre-versions of FluentAssertions 8 have continued to be released under the Apache 2.0 license indicates that this was done in the short term - for whatever reason, most likely financial interest.

Even though the creators most likely have a very high share of the source code and ideas, FluentAssertions has been a popular project with contributors, both in code and ideas. The switch to a commercial license is a slap in the face for all those who have contributed to the project - especially since the financial profit will most likely remain solely with the owners, although many others have contributed to the project - even with the awareness that this is an Apache 2.0 license. Whether the switch to a commercial license is legal at all, hopefully professionals will take care of that (at least this is an active discussion in the Fluent Assertion License PR).

Yes, we need a solution for sustainable open source projects - but not like this. This is an undignified treatment of everyone who has worked on this project and an immense loss of trust in the entire ecosystem. That is not sustainable open-source software.

What now?

As in the case of Moq, confidence in the project is now shaken. The commercial license is very vague, it is incredibly expensive (130$ for a syntax-sugar library!). The good thing is: FluentAssertions is functionally not an important library. The main purpose of this library is to make the assertions in Unit Test look pretty.

FluentAssertions simply turns Assert.IsTrue(myVar) into myVar.Should().BeTrue(). This is what probably over 99% of users appreciate and use in FluentAssertions.

Sticky version

The simplest variant is not to use version 8. To do this, we set the latest Apache 2.0 version in our csproj or Directory.Packages.props sticky:

XML
<PackageReference Include="PackageName" Version="[7.0.0]" />

Simple Asserts

To get rid of FluentAssertions completely, the easiest way is to remove it and replace it with simple asserts. In most cases, this is very easy and quick to do.

GitHub Copilot and ChatGPT with the GPO 4o model provide excellent results for converting FluentAssertions assertions into simple asserts in just a few seconds.

replace FluentAssertions code with simple asserts

Migrate to Shoudly

FluentAssertions is certainly the most comprehensive assertion library - but who really uses all the features? As I said, well over 99% will limit themselves to the syntax sugars - and for that there are alternatives like Shoudly .

Copilot is able to convert most FluentAssertions assertions into Shouldly. So it only costs us a few seconds per file to replace FluentAssertions.

myVar.Should().BeTrue() becomes myVar.ShouldBe(true).

A custom implementation

The Fluent API of FluentAssertions is extensive, but not complex. Most of the features are not used, so we can generate a Basic API with Copilot, which costs 20 seconds.

create a fluent testing class api for the most important stuff so I can verify my tests with like “Hello”.Assert().IsNotNull()

C#
 1public static class FluentTestExtensions
 2{
 3    public static FluentTest<T> Assert<T>(this T value)
 4    {
 5        return new FluentTest<T>(value);
 6    }
 7
 8    public class FluentTest<T>
 9    {
10        private readonly T _value;
11
12        public FluentTest(T value)
13        {
14            _value = value;
15        }
16
17        public FluentTest<T> IsNotNull()
18        {
19            Assert.IsNotNull(_value, "Expected value to not be null.");
20            return this;
21        }
22
23        public FluentTest<T> IsNull()
24        {
25            Assert.IsNull(_value, "Expected value to be null.");
26            return this;
27        }
28
29        public FluentTest<T> IsEqualTo(T expected)
30        {
31            Assert.AreEqual(expected, _value, $"Expected value to be {expected}, but was {_value}.");
32            return this;
33        }
34
35        public FluentTest<T> IsNotEqualTo(T unexpected)
36        {
37            Assert.AreNotEqual(unexpected, _value, $"Expected value to not be {unexpected}, but it was.");
38            return this;
39        }
40
41        public FluentTest<T> IsOfType<U>()
42        {
43            Assert.IsInstanceOfType(_value, typeof(U), $"Expected value to be of type {typeof(U).Name}, but was {(_value == null ? "null" : _value.GetType().Name)}.");
44            return this;
45        }
46
47        public FluentTest<T> IsNotOfType<U>()
48        {
49            Assert.IsNotInstanceOfType(_value, typeof(U), $"Expected value to not be of type {typeof(U).Name}, but it was.");
50            return this;
51        }
52
53        public FluentTest<T> Satisfies(Func<T, bool> predicate, string message = "Value did not satisfy the condition.")
54        {
55            Assert.IsTrue(predicate(_value), message);
56            return this;
57        }
58
59        public FluentTest<T> Fails(Func<T, bool> predicate, string message = "Value unexpectedly satisfied the condition.")
60        {
61            Assert.IsFalse(predicate(_value), message);
62            return this;
63        }
64    }
65}
66
67// Example usage:
68public static class Program
69{
70    public static void Main()
71    {
72        "Hello"
73            .Assert()
74            .IsNotNull()
75            .IsEqualTo("Hello")
76            .IsNotEqualTo("World")
77            .IsOfType<string>()
78            .Satisfies(s => s.Length > 3, "String length should be greater than 3.");
79
80        42
81            .Assert()
82            .IsNotNull()
83            .IsEqualTo(42)
84            .Satisfies(x => x > 0, "Number should be positive.")
85            .IsOfType<int>()
86            .Fails(x => x < 0, "Number should not be negative.");
87
88        Console.WriteLine("All assertions passed.");
89    }
90}

Boom, I recreated the most important features of FluentAssertions in 20 seconds - without mentioning the name.

Conclusion

I really liked FluentAssertions. It’s a great, intuitive project - and certainly a life’s work that has made a name for itself in the community. But one should not overestimate the value of this framework. FluentAssertions is now said to cost as much per person per year as a new Jetbrains C# IDE Rider - really? I want to smoke that stuff too.

FluentAssertions is not an irreplaceable product. It’s a human relief - but in times of AI support like Copilot, do I really still need it? I do not think so. You should look at the value realistically.

It will always remain a mystery to me how one can destroy a life’s work like FluentAssertions in a single rash or ill-considered action.

Bye FluentAssertions! Was a great time.

Related articles

Containerizing .NET in 2026 Without a Dockerfile

Oct 20, 2026 - 11 min read

Containerizing .NET in 2026 Without a Dockerfile

Most .NET Dockerfiles repeat the same five steps: restore, publish, select the matching Microsoft runtime image, copy the output and start …

Problem Details in ASP.NET Core and .NET 11

Oct 5, 2026 - 12 min read

Problem Details in ASP.NET Core and .NET 11

builder.Services.AddProblemDetails() registers infrastructure. It does not create an error contract. An ASP.NET Core request can fail during …

Resilience in .NET with Microsoft.Extensions.Resilience

Sep 21, 2026 - 11 min read

Resilience in .NET with Microsoft.Extensions.Resilience

Retries are the most visible resilience strategy and the easiest one to misuse. Repeating a failing call can recover from a short network …


BEN ABT

BEN ABT

Ben is Chief Engineering Officer and Principal Software Engineer at Medialesson.de, with a strong focus on .NET and Microsoft Azure. In his professional role, he designs and builds highly scalable platforms for hybrid and cloud-based scenarios. He also advises companies and C-levels on migrating to the sovereign cloud.

He runs myCSharp.de, the largest and most active German-speaking C# community forum, actively contributes to both his own and external open-source projects and regularly shares his knowledge through his blog, at community events, conferences and as a writer for technical magazines.

Let's Work Together

Looking for an experienced Platform Architect or Engineer for your next project? Whether it's cloud migration, platform modernization or building new solutions from scratch - I'm here to help you succeed.

New Platforms

Modernization

Training & Consulting

Contact Me
X Facebook LinkedIn WhatsApp
Back Next Blog Post

Open for work!

Contact Me
BEN ABT BEN ABT Software Engineer · Microsoft MVP Passionate about .NET, Azure, performance optimization and sustainable software engineering.

Medialesson GmbH Logo

Microsoft MVP Logo

Recent posts

View all
Stop Using nginx as Your Default Static File Server in Docker

Stop Using nginx as Your Default Static File Server in …

Oct 24, 2026
Containerizing .NET in 2026 Without a Dockerfile

Containerizing .NET in 2026 Without a Dockerfile

Oct 20, 2026
Problem Details in ASP.NET Core and .NET 11

Problem Details in ASP.NET Core and .NET 11

Oct 5, 2026
Resilience in .NET with Microsoft.Extensions.Resilience

Resilience in .NET with Microsoft.Extensions.Resilience

Sep 21, 2026
What Matters in ASP.NET Core 11

What Matters in ASP.NET Core 11

Sep 14, 2026

Tags

.NET (192) Csharp (96) ASP.NET Core (48) Azure (41) DevOps (17) Docker (14) Microsoft (14) EF Core (11) Microsoft MVP (11) AI (10) GitHub (10) GitHub Copilot (10) ASP.NET (9) Security (9) Synology (9) Architecture (8) Raspberry (8) Azure Functions (7) Cloudflare (7) Bicep (6)
benjamin-abt.com

About BEN

Benjamin Abt is a Software Engineer, Platform Architect and Microsoft MVP specializing in .NET, Azure, cloud architecture, performance optimization and sustainable software development.

Connect

  • Follow me on GitHub
  • Follow me on LinkedIn
  • Follow me on Mastodon
  • Microsoft MVP profile
  • Follow SchwabenCode on GitHub
  • Follow me on X

Quick Links

  • Portfolio
  • Blog
  • Workshops & Training
  • Publications
  • Get in Touch
  • Sitemap
Open for Work

© Copyright Benjamin Abt & SchwabenCode | 2011 - 2026

Content licensed under CC BY 4.0 unless otherwise noted.

  • Impressum
  • Privacy
  • Contact