3

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<ObjectAssertions>' does not contain a definition for 'Which' and no accessible extension method 'Which' accepting a first argument of type 'AndConstraint<ObjectAssertions>' could be found (are you missing a using directive or an assembly reference?)

What I'm doing wrong?

geckos
  • 5,687
  • 1
  • 41
  • 53
  • Use `And` instead of `Which`. The former is used for chaining. The latter is when the previous assertion changes the type of the object that is being asserted. – Dennis Doomen May 06 '21 at 18:36

1 Answers1

5

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`
Tullo_x86
  • 2,573
  • 25
  • 27