1 minute read

3 min read 777 words

While xUnit’s Assert class is powerful, it can sometimes feel clunky or less intuitive. FluentAssertions is a popular library that allows you to write assertions in a more natural, “fluent” way that reads like a sentence.


1. Installation & Setup

To use FluentAssertions in your test project, you need to install the NuGet package:

dotnet add package FluentAssertions

Once installed, add the following using directive to your test files:

using FluentAssertions;

2. Basic Assertions

The core of FluentAssertions is the .Should() extension method.

Strings

string name = "John Doe";

name.Should().StartWith("John");
name.Should().EndWith("Doe");
name.Should().Contain(" ");
name.Should().HaveLength(8);
name.Should().BeEquivalentTo("JOHN DOE"); // Case-insensitive

Numbers

int result = 42;

result.Should().Be(42);
result.Should().BeGreaterThan(40);
result.Should().BeInRange(1, 100);

Booleans & Nulls

bool isReady = true;
isReady.Should().BeTrue();

object myObj = null;
myObj.Should().BeNull();

3. Collection Assertions

Working with collections is significantly easier with FluentAssertions.

var numbers = new[] { 1, 2, 3, 4, 5 };

numbers.Should().HaveCount(5);
numbers.Should().Contain(3);
numbers.Should().OnlyHaveUniqueItems();
numbers.Should().StartWith(1).And.EndWith(5);
numbers.Should().BeInAscendingOrder();

4. Object Graph Comparison

One of the most powerful features is BeEquivalentTo. It performs a deep comparison of two objects, comparing their properties rather than their references.

var expected = new User { Id = 1, Name = "Alice" };
var actual = new User { Id = 1, Name = "Alice" };

// xUnit would fail this if it's a reference comparison
// actual.Should().BeEquivalentTo(expected); 

You can even exclude specific properties:

actual.Should().BeEquivalentTo(expected, options => options.Excluding(u => u.Id));

5. Exception Assertions

Testing for exceptions is much more readable than the standard Assert.Throws.

Action act = () => service.DoSomething(null);

act.Should().Throw<ArgumentNullException>()
   .WithParameterName("input")
   .WithMessage("*cannot be null*");

6. Why use FluentAssertions?

Feature Standard xUnit FluentAssertions
Readability Assert.Equal(expected, actual) actual.Should().Be(expected)
Fail Messages Often generic Very descriptive (explains why it failed)
Chaining Not possible obj.Should().NotBeNull().And.BeOfType<User>()
Collections Requires multiple asserts Powerful single-line assertions

7. References & Further Reading


C# Interview Series

Leave a comment