How to use Fluent Assertions in C#

By FoxLearn 1/6/2025 8:30:47 AM   175
Using the Fluent Assertions library in C# can help achieve this by making tests simple, readable, and expressive.

Unit testing is crucial for verifying both implicit and explicit assumptions in code, leading to fewer errors. Fluent Assertions enhances unit tests, making them more concise and easier to understand.

To add the Fluent Assertions to your project, right-click the project in Solution Explorer, choose "Manage NuGet Packages," search for "Fluent Assertions," and install it.

Alternatively, you can install it using the NuGet Package Manager console with the command:

PM> Install-Package FluentAssertions

What is Fluent Assertions?

Fluent Assertions is a library of extension methods designed to make assertions in unit tests more readable and intuitive.

For example, how you can use Fluent Assertions to write a unit test that checks multiple conditions on a string in a clear and readable manner:

[Fact]
public void Verify_That_A_String_Contains_Specific_Patterns()
{
    string actual = "The quick brown fox jumps over the lazy dog";
    var result = actual.Should().Contain("quick")
                       .And.StartWith("The")
                       .And.EndWith("dog")
                       .And.HaveLength(43);
}

In this example, Fluent Assertions makes the test both simple to write and easy to read, with multiple assertions chained together to verify different conditions on the string.

Subject identification using Fluent Assertions Be() in C#

One of the standout features of Fluent Assertions is its ability to automatically extract the name of the subject and include it in assertion failure messages. This makes it easier to understand exactly which variable or object failed the test.

[Fact]
public void Verify_Subject_Identification()
{
    string email = "[email protected]";
    email.Should().Be("[email protected]");
}

In this case, if the test fails, Fluent Assertions will display the variable name (email) along with the expected and actual values in the failure message.

Here’s another example showing how you can verify the value of an integer:

[Fact]
public void Verify_The_Value_Of_An_Integer()
{
    int age = 30;
    age.Should().Be(30);
}

You can also add a custom failure message to your assertions, making the test more descriptive and easier to diagnose when something goes wrong:

[Fact]
public void Verify_The_Value_Of_An_Integer_Variable()
{
    int count = 5;
    count.Should().Be(10, "because the variable 'count' should represent the total number of items");
}

Writing Basic Unit Test Assertions in C#

Consider the following Product class:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public decimal Price { get; set; }
}

You can apply assertions on reference types, such as an instance of the Product class, like this:

[Fact]
public void Verify_The_Value_And_Type_Of_A_Product()
{
    Product product = new Product
    {
        Id = 101,
        Name = "Laptop",
        Price = 799.99
    };

    product.Should().NotBeNull();
    product.Should().BeOfType<Product>();
    product.Name.Should().Be("Laptop");
    product.Price.Should().BeGreaterThan(0);
}

You can also apply assertions on string values, like in this example:

[Fact]
public void Verify_The_Value_Of_A_String_Description()
{
    string description = "This is a premium quality product.";
    description.Should().NotBeNullOrEmpty();
    description.Should().Contain("premium");
    description.Should().StartWith("This");
}

For boolean variables.

[Fact]
public void Verify_The_Value_Of_A_Boolean_Flag()
{
    bool isAvailable = true;
    isAvailable.Should().BeTrue();

    isAvailable = false;
    isAvailable.Should().BeFalse();
}

To verify the value of a double variable, you can use the following code:

[Fact]
public void Verify_The_Value_Of_A_Double_Variable()
{
    double discount = 15.5;

    discount.Should().Be(15.5);
    discount.Should().BeGreaterThan(0);
    discount.Should().BeLessThanOrEqualTo(50);
    discount.Should().BeInRange(0, 20);
}

And to verify the value of an integer variable, you can apply a set of assertions like this:

[Fact]
public void Verify_The_Value_Of_A_Integer_Quantity()
{
    int quantity = 150;

    quantity.Should().Be(150);
    quantity.Should().BeGreaterThan(100);
    quantity.Should().BeLessThan(200);
    quantity.Should().BeInRange(1, 200);
}

Verify Object Property Values in C#

For example, how you can verify the ID, Name, and Price properties of a Product class without using Fluent Assertions:

[Fact]
public void Verify_The_Product_Properties_Without_Fluent_Assertions()
{
    int productId = 101;
    string productName = "Smartphone";
    decimal productPrice = 499.99;

    Assert.Equal(101, productId);
    Assert.Equal("Smartphone", productName);
    Assert.Equal(499.99, productPrice);
}

Now, let's rewrite this test using Fluent Assertions for a cleaner and more expressive approach:

[Fact]
public void Verify_The_Product_Properties_With_Fluent_Assertions()
{
    int productId = 101;
    string productName = "Smartphone";
    decimal productPrice = 499.99;

    productId.Should().Be(101);
    productName.Should().Be("Smartphone");
    productPrice.Should().Be(499.99);
}

With Fluent Assertions, the code becomes more concise, and the assertions are easier to read. In case of test failure, the failure messages will be more descriptive, helping you understand exactly which property failed and why.