Search Results for

    Show / Hide Table of Contents

    NUnit2050

    NUnit 4 no longer supports string.Format specification

    Topic Value
    Id NUnit2050
    Severity Error
    Enabled True
    Category Assertion
    Code UpdateStringFormatToInterpolatableStringAnalyzer

    Description

    Replace format specification with interpolated string.

    Motivation

    In order to get better failure messages, NUnit4 uses CallerArgumentExpression to include the expression passed in for the actual and constraint parameters. These are parameters automatically supplied by the compiler.

    To facilitate this, we needed to drop support for composite formatting. All NUnit4 asserts only allow a single message parameter which can be either a simple string literal or a interpolatable string.

    This analyzer needs to be run when still building against NUnit3 as otherwise your code won't compile. When usages of the new methods with params are detected, the associated CodeFix will convert the format specification into an interpolated string.

    The affected methods are:

    Assert.Pass
    Assert.Fail
    Assert.Warn
    Assert.Ignore
    Assert.Inconclusive
    Assert.That
    Assume.That
    

    Once you moved to NUnit4 the analyzer has some limited functionality as there are a few cases with Assert.That or Assume.That where your NUnit3 code will compile on NUnit4, but not the way you want it. Here what you think are parameters to a format specification are actually interpreted as the actual and constraint expression strings. Unfortunately you only find that out when the test fails, which could be never.

    How to fix violations

    The following code, valid in NUnit3:

    [TestCase(4)]
    public void MustBeMultipleOf3(int value)
    {
        Assert.That(value % 3, Is.Zero, "Expected value ({0}) to be multiple of 3", value);
    }
    

    Will fail with the following message:

    Expected value (4) to be multiple of 3
    Expected: 0
    But was:  1
    

    The associated CodeFix for this Analyzer rule will convert the test into:

    [TestCase(4)]
    public void MustBeMultipleOf3(int value)
    {
        Assert.That(value % 3, Is.Zero, $"Expected value ({value}) to be multiple of 3");
    }
    

    The failure message for NUnit4 becomes:

    Expected value (4) to be multiple of 3
    Assert.That(value % 3, Is.Zero)
    Expected: 0
    But was:  1
    

    As the [CallerMemberExpression] parameters are string, some of NUnit 3.x code compiles, but when failing show the wrong message:

    [TestCase("NUnit 4", "NUnit 3")]
    public void TestMessage(string actual, string expected)
    {
        Assert.That(actual, Is.EqualTo(expected), "Expected '{0}', but got: '{1}'", expected, actual);
    }
    

    When using NUnit3, this results in:

      Expected 'NUnit 3', but got: 'NUnit 4'
      String lengths are both 7. Strings differ at index 6.
      Expected: "NUnit 3"
      But was:  "NUnit 4"
      -----------------^
    

    But when using NUnit4, we get:

     Message:
      Expected '{0}', but got: '{1}'
    Assert.That(NUnit 3, NUnit 4)
      String lengths are both 7. Strings differ at index 6.
      Expected: "NUnit 3"
      But was:  "NUnit 4"
      -----------------^
    

    Where the format string is treated as the message and its arguments are interpreted as the actual and expected expressions! After applying the code fix the code looks like:

    [TestCase("NUnit 4", "NUnit 3")]
    public void TestMessage(string actual, string expected)
    {
        Assert.That(actual, Is.EqualTo(expected), $"Expected '{expected}', but got: '{actual}'");
    }
    

    and the output:

     Message:
      Expected 'NUnit 3', but got: 'NUnit 4'
    Assert.That(actual, Is.EqualTo(expected))
      String lengths are both 7. Strings differ at index 6.
      Expected: "NUnit 3"
      But was:  "NUnit 4"
      -----------------^
    

    Configure severity

    Via ruleset file

    Configure the severity per project, for more info see MSDN.

    Via .editorconfig file

    # NUnit2050: NUnit 4 no longer supports string.Format specification
    dotnet_diagnostic.NUnit2050.severity = chosenSeverity
    

    where chosenSeverity can be one of none, silent, suggestion, warning, or error.

    Via #pragma directive

    #pragma warning disable NUnit2050 // NUnit 4 no longer supports string.Format specification
    Code violating the rule here
    #pragma warning restore NUnit2050 // NUnit 4 no longer supports string.Format specification
    

    Or put this at the top of the file to disable all instances.

    #pragma warning disable NUnit2050 // NUnit 4 no longer supports string.Format specification
    

    Via attribute [SuppressMessage]

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion",
        "NUnit2050:NUnit 4 no longer supports string.Format specification",
        Justification = "Reason...")]
    
    • Edit this page
    In this article
    Back to top Generated by DocFX | Copyright (c) 2018- The NUnit Project - Licensed under CC BY-NC-SA 4.0