Search code examples
c#.netunit-testingxunit.netfluent-assertions

Using FluentAssertions .Should().NotBeNull() instead of Assert.NotNull(record.Message) give a Possible NullReference smell


I have a little question about FluentAssertions and record.Should().NotBeNull();

Here i use XUnit for unit testing and his Record class.

Take this code with Record:

    // i expect this code will explode and the record will be not null
    var record = await Record.ExceptionAsync(() =>
        sut.SomeActionThatExplode(new SomeDto())
    );        

So, here i use XUnit.Assert methods:

    Assert.IsType<InvalidDataException>(record);
    Assert.NotNull(record.Message);
    Assert.Equal("abcs",record.Message); // here all is ok! and i have no smells

I have no smells using this method and everything is fine as i expected.

In the following example i do the same assertion, but using FluentAssertions instead:

    record.Should().BeOfType<InvalidDataException>();
    record.Should().NotBeNull();
    record.Message.Should().NotBeNull(); // here i have a smell issue
    record.Message.Should().Be("abcs");

When i use FluentAssertions i got a Possible 'System.NullReferenceException' smell on the record.Message.Should().NotBeNull() line for the record.

Here a snapshot:

enter image description here

Is there something i do wrong? how can i avoid smell using only FluentAssertion methods? Maybe i should use a mix of both like this:

    Assert.IsType<InvalidDataException>(record);
    Assert.NotNull(record.Message);
    record.Message.Should().NotBeNull();
    record.Message.Should().Be("abcs"); // that's fine an i got no smells.

However i wish use only FluentAssertions to achieve no smells on my code.

Thanks in advance.

Cose belle!


Solution

  • The issue you're encountering is a known behavior with FluentAssertions. Currently the vs static code analyzer doesn't recognize that Should().NotBeNull() guarantees that the object isn't null. Some Devs are using the null-forgiving operator! in their unit tests to tell the compiler that you're sure the object isn't null. E.G.:

    record.Should().BeOfType<InvalidDataException>();
    record.Should().NotBeNull();
    record!.Message.Should().NotBeNull();
    record!.Message.Should().Be("abcs");
    

    This should resolve the null reference warning while allowing you to continue using FluentAssertions. However, please note that using ! should be done with caution and im my opinion only in tests. as it turns off null checking for that reference, which could lead to runtime errors if used in production code.