Search code examples
c#fluent-assertions

How to use `Which` in FluentAssertions?


I'm using fluent assertions and I have this test:

result.Should().NotBeNull();
result.Link.Should().Equals("https://someinvoiceurl.com");

which works fine but when I try this

result.Should().NotBeNull()
.Which.Link.Equals("https://someinvoiceurl.com");

I got this error

'AndConstraint' does not contain a definition for 'Which' and no accessible extension method 'Which' accepting a first argument of type 'AndConstraint' could be found (are you missing a using directive or an assembly reference?)

What I'm doing wrong?


Solution

  • The problem here is that .NotBeNull() is not generic (it is an extension on ObjectAssertions rather than GenericObjectAssertions), so it can't chain the type information to later calls.

    I think this is a flaw in the library design, personally, but it is easily worked around by substituting .NotBeNull() with .BeOfType<T>() as so:

    result.Should().BeOfType<ThingWithLink>() // assertion fails if `result` is null
        .Which.Link.Should().Be("https://someinvoiceurl.com");
    

    Of course, if you assert on your ThingWithLink type a lot, it could be worth writing a custom assertion so that you can be "more fluent":

    result.Should().BeOfType<ThingWithLink>()
        .And.HaveLink("https://someinvoiceurl.com");
    

    If you need something more ad-hoc, you can always just use .BeEquivalentTo() to do structural comparison:

    result.Should().NotBeNull()
        .And.BeEquivalentTo(new { Link = "https://someinvoiceurl.com" }); // ignores all members on `result` except for `result.Link`