Back to Nunit

NUnit3001

docs/articles/nunit-analyzers/NUnit3001.md

latest3.9 KB
Original Source

NUnit3001

Expression was checked in an ClassicAssert.NotNull, ClassicAssert.IsNotNull or Assert.That call

TopicValue
IdNUnit3001
SeverityInfo
EnabledTrue
CategorySuppressor
CodeDereferencePossiblyNullReferenceSuppressor

Description

This rule check diagnostics reported by the CS8601-CS8607 and CS8629 compiler errors:

CS8602: Dereference of a possibly null reference.

It then checks the previous statements for one of:

  • ClassicAssert.NotNull(...)
  • ClassicAssert.IsNotNull(...)
  • Assert.That(..., Is.Not.Null)

For the same expression as the one that raised the original compiler error. If found, the compiler error is suppressed.

The rule also covers CS8629: Nullable value type may be null

In this case, the previous statement is allowed to be one of:

  • Assert.That(...HasValue)
  • Assert.That(...HasValue, Is.True)
  • ClassicAssert.True(...HasValue)
  • ClassicAssert.IsTrue(...HasValue)

The exception is that if the statement is part of an Assert.Multiple it is not suppressed, as in this case the statement containing the compiler error will be executed.

Motivation

csharp
[TestFixture]
internal sealed class SomeClassFixture
{
    private SomeClass instance;

    [SetUp]
    public void Setup()
    {
        instance = new SomeClass();
    }

    [Test]
    public void Test()
    {
        string? result = instance.MethodUnderTest();
        Assert.That(result, Is.Not.Null);
        Assert.That(result.Length, Is.GreaterThan(0));
    }

    [Test]
    public void TestMultiple()
    {
        string? result = instance.MethodUnderTest();
        Assert.Multiple(() =>
        {
            Assert.That(result, Is.Not.Null);
            Assert.That(result.Length, Is.GreaterThan(0));
        });
    }
}

In the above fixture the compiler would give a warnings because result can be null and the compiler knows nothing about the Assert.That(result, Is.Not.Null); statement.

The first occurrence - in the Test method - will be suppressed, the second - in the TestMultiple - will not.

How to fix violations

Ensure that the reference is not null before dereferencing it. This can be done using regular C# language constructs or NUnit assertions.

<!-- start generated config severity -->

Configure severity

The rule has no severity, but can be disabled.

Via ruleset file

To disable the rule for a project, you need to add a ruleset file

xml
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="NUnit.Analyzer Suppressions" Description="DiagnosticSuppression Rules" ToolsVersion="12.0">
  <Rules AnalyzerId="DiagnosticSuppressors" RuleNamespace="NUnit.NUnitAnalyzers">
    <Rule Id="NUnit3001" Action="Info" /> <!-- Possible Null Reference -->
    <Rule Id="NUnit3002" Action="Info" /> <!-- NonNullableField/Property is Uninitialized -->
    <Rule Id="NUnit3003" Action="Info" /> <!-- Avoid Uninstantiated Internal Classes -->
    <Rule Id="NUnit3004" Action="Info" /> <!-- Types that own disposable fields should be disposable -->
  </Rules>
</RuleSet>

and add it to the project like:

xml
<PropertyGroup>
  <CodeAnalysisRuleSet>NUnit.Analyzers.Suppressions.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>

For more info about rulesets see MSDN.

Via .editorconfig file

This is currently not working. Waiting for Roslyn

ini
# NUnit3001: Expression was checked in an ClassicAssert.NotNull, ClassicAssert.IsNotNull or Assert.That call
dotnet_diagnostic.NUnit3001.severity = none
<!-- end generated config severity -->