【问题标题】:Any way to ignore Possible Null Reference Exception warnings when using Assert statements?使用 Assert 语句时有什么方法可以忽略可能的空引用异常警告?
【发布时间】:2012-03-23 15:22:27
【问题描述】:

我不想完全禁用警告,只是在 Assert 语句中。

例如,如果我有以下两行

var someObject = GetObject();
Assert.IsNotNull(someObject, "someObject should not be null");
Assert.AreEqual(expectedValue, someObject.SomeProperty);

我将在someObject.SomeProperty 的第二行收到可能的空引用警告。是否可以在某个呼叫中禁用警告,例如Assert.AreEqual

由于这是很多单元测试的问题,我不想在测试中乱扔 ReSharper 禁用代码。

现在我能想到的唯一选择是将每个Assert.IsNotNull 调用更改为

var someObject = GetObject();
if(someObject == null)
{
  Assert.Fail("someObject is null");
  return;
}

虽然这似乎违背了拥有Assert.IsNotNull 的初衷。只是想知道是否有更好的方法。

【问题讨论】:

  • 你能发布一个更完整的例子吗?我无法重现这个;使用 NUnit 的断言库时,添加 Assert.IsNotNull 会删除警告 - 并且它是否在测试中没有效果。
  • @JamesWorld,我正在使用 MBUnit,不确定这是否会有所不同。我发布的代码确实使用 MBUnit 2.4.2 和 ReSharper 6.1 给出了警告。我知道它是否在测试中并不重要,但我只关心在测试类中禁用它。在其他任何地方都应该启用它。
  • 是的,我发现了 MBUnit 的使用,这就是我说我使用 NUnit 的原因。我将我的测试切换到 MBUnit,发现它并没有消除警告。问题一定在于它们的实现方式不同。

标签: c# unit-testing mbunit resharper-6.1


【解决方案1】:

我不知道您使用的具体库,但我会尝试类似的东西

Assert.IsTrue(someObject != null);

或者,为了完整起见,

Assert.IsNotNull(someObject, "someObject must not be null");
Assert.IsNotNull(someObject.SomeProperty, "SomeProperty must not be null either");
Assert.SomethingElse(...);

【讨论】:

  • 感谢您的回答,但问题仍然存在。即使我断言该对象并且该属性不为空,警告也不在乎并给出警告。只有当我执行object == null 并退出该方法时,警告才会消失。
  • @Brandon 出于好奇,尽管有警告,但测试是否按预期通过和失败?
  • 是的。这更像是一个挑剔的问题。我只是不喜欢解决方案范围的检查充满一堆实际上不应该是警告的警告。这不会影响实际代码或测试或任何东西。
  • @Brandon 哦,我现在明白了,它们来自 ReSharper,而不是来自编译器……我的错。那个愚蠢的东西应该提供指示它闭嘴的设施,但我从未使用过它,所以我恐怕无法提供进一步的建议。无论如何,它们都不是真正的警告(它们不是来自编译器,对吗?),所以我可能最终会在你的情况下忽略它们......但我'当谈到最佳实践时,我非常懒惰......
【解决方案2】:

将此添加到您的项目中:

public static class AssertionsExtensions
{
    [NotNull]
    public static TSubject ShouldNotBeNull<TSubject>([CanBeNull] this TSubject source,
        [CanBeNull] string because = "", [CanBeNull] [ItemCanBeNull] params object[] reasonArgs)
    {
        source.Should().NotBeNull(because, reasonArgs);

        // ReSharper disable once AssignNullToNotNullAttribute
        return source;
    }
}

然后这样使用,例如:

            // Assert
            succeeded.Should().Be(true, "<USB loopback cable must be connected and COM port must be correct.>");
            DeviceStatus deviceStatusNotNull = testRunner.Result.ShouldNotBeNull();
            deviceStatusNotNull.DeviceAddress.Should().Be(deviceAddress);
            deviceStatusNotNull.IsInNetwork.Should().Be(true);

【讨论】:

    【解决方案3】:

    如果我没记错的话,你的问题是当没有为每个对象检查 null 时,resharper 会发出警告。您可以修改 resharper 规则以不在测试类中给出空警告。 Here 是一个关于更改测试方法的 ReSharper 命名样式的链接。

    【讨论】:

    • 当您开始将每个单词写成一个单词时,您就知道自己编写的程序太多了。 :) 您能否提供有关如何执行此操作的步骤?我如何告诉 Resharper 考虑什么测试类?
    • @Brandon 你让我笑了:) 请看看; atombrenner.blogspot.com/2010/07/…
    • -1 我认为你错了。警告的出现并不特定于测试类。
    • @JamesWorld 警告的出现并不特定于测试类,你是对的,但是如果我没有错的话,布兰登需要的是只在测试类中禁用警告。
    • 禁用大量警告绝不是一个好主意 - 这会隐藏真正关注的警告。
    【解决方案4】:

    使用 NUnit 代替 MBUnit。 NUnit 的 Assert.IsNotNull() 实现被认为是保证不为空,而 MBUnit 则不是。

    【讨论】:

    • 如何保证 Assert.That(result, Is.Not.Null) ?
    【解决方案5】:

    您可以使用 R# 外部注释来抑制警告(请参阅http://grahamrhay.wordpress.com/2011/01/09/external-annotations/)。

    您使用的是哪个版本的 MbUnit/Gallio?

    【讨论】:

      【解决方案6】:

      如果参数为空,您可以使用 ContractAnnotations 来指示执行停止。见jetbrains contract annotations。示例类:

       public static class FluentExtensions
       {
              //see: https://www.jetbrains.com/help/resharper/2017.3/Contract_Annotations.html
              [ContractAnnotation("null => stop")]
              public static void ShouldNotBeNull(this object objToTest)
              {
                  objToTest.Should().NotBeNull();
              }   
      
       }
      

      用法:

      doc.ShouldNotBeNull();
      doc.Content.ShouldNotBeNull();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-10-19
        • 1970-01-01
        • 2022-06-25
        • 2020-04-18
        • 1970-01-01
        • 1970-01-01
        • 2013-08-11
        相关资源
        最近更新 更多