Multiple assertions using Fluent Assertions library
Asked Answered
O

4

31

It seems that Fluent Assertions doesn't work within NUnit's Assert.Multiple block:

Assert.Multiple(() =>
    {
        1.Should().Be(2);
        3.Should().Be(4);
    });

When this code is run, the test fails immediately after the first assertion, so the second assertion is not even executed.

But, if I use NUnit's native assertions, I get the results I want:

Assert.Multiple(() =>
    {
        Assert.That(1, Is.EqualTo(2));
        Assert.That(3, Is.EqualTo(4));
    });

And the output contains details on both failures:

Test Failed - ExampleTest()

Message: Expected: 2 But was: 1

Test Failed - ExampleTest()

Message: Expected: 4 But was: 3

How can I get similar results using Fluent Assertions with NUnit?

Own answered 30/8, 2017 at 0:0 Comment(0)
G
56

You can do this with assertion scopes like this:

using (new AssertionScope())
{
    5.Should().Be(10);
    "Actual".Should().Be("Expected");
}
Geometrize answered 20/7, 2018 at 9:34 Comment(0)
T
10

You may either:

1: Use AssertionScope (as pointed by @RonaldMcdonald):

using (new AssertionScope())
{
  (2 + 2).Should().Be(5);
  (2 + 2).Should().Be(6);
}

Or:

2. Use FluentAssertions.AssertMultiple NuGet package (the tiny package created by myself):

AssertMultiple.Multiple(() =>
{
    (2 + 2).Should().Be(5);
    (2 + 2).Should().Be(6);
});

And, when you import static member:

using static FluentAssertions.AssertMultiple.AssertMultiple;

//...

Multiple(() =>
{
    (2 + 2).Should().Be(5);
    (2 + 2).Should().Be(6);
});
Treillage answered 7/11, 2019 at 9:7 Comment(2)
That is tiny. That's a lot for a little bit of sugar; maybe just point folks directly to the 10 lines they can just copy into their test project or personal test library? (And you could make it even shorter.)Larry
@MarcL. The benefit of having it as a (even tiny) dependency is that it is being updated over time. However, as the code is posted on GitHub, please feel free to grab the code parts you need and use them without installing dependencies.Pericope
O
1

Sorry, short answer is that you can't currently get the same results with Fluent assertions. The NUnit assertions have special logic in them that knows they are in a multiple assertion block. In that case, they don't throw an exception on failure, but instead register the failure with the parent multiple assert which will report the error when it is complete.

Fluent assertions will need to do the same thing internally. That could be as simple as chaining to the NUnit assertions, or even just calling Assert.Fail. I would recommend filing an issue with the Fluent assertions project. Feel free to point them to me on GitHub (@rprouse) if they need help on how the NUnit internals work.

Ommatophore answered 30/8, 2017 at 0:43 Comment(3)
For reference purposes, the equivalent in FluentAssertions is the AssertionScope.Bemused
@DennisDoomen If I use AssertionScope and call two methods within it, each having a single assert, I get the following message in Test Explorer: Expected value to be 2, but found 1. Expected value to be 4, but found 3. Can I customize this message? For example, include method name in it, so I can see in which method the assertion fails?Own
Each of these methods except an extra parameter to provide the reason of the expected outcome.Bemused
A
1

When using a recent version of C# (after 6), you can simply use ValueTuples.

Here is an example I use in one of my unit tests made with xUnit and FluentAssertions:

[Theory]
[InlineData(70.01, 180, 1.80, 21.61)]
public void ValueTupleTest(decimal weightInKg, int lengthInCm, decimal expectedLengthInM, decimal expectedBmi)
{
    var instance = new HealthDescription(weightInKg, lengthInCm);
    (instance.LengthInM, instance.Bmi, instance.WeighthInKg).Should()
                .Be((expectedLengthInM, expectedBmi, weightInKg));
}

When using ValueTuples, you can easily wrap multiple values into one object. So formally, it's still one assertion. However, there are multiple validations effectively.

Aerophone answered 14/8, 2023 at 12:54 Comment(1)
This is a pretty neat shortcut, but what does an assertion failure look like? Are the elements sufficiently differentiated from one another? What if you use an anonymous type?Larry

© 2022 - 2024 — McMap. All rights reserved.