【问题标题】:Intellij IDEA warnings for @Nonnull annotation in unit tests单元测试中@Nonnull 注释的 Intellij IDEA 警告
【发布时间】:2015-09-27 16:34:53
【问题描述】:

假设我有一个方法,其中一些参数使用 javax @Nonnull 注释进行了注释。

public Something supply(@Nonnull SomeObject someObject) {
    (...)
    if (someObject == null) throw new ValidationException("Required parameter is null");
    (...)
}

当我尝试使用显式 null 参数调用此方法时,IDE 会正确通知我,如下所示:

somethingSupplier.supply(null);

现在我要做的是创建单元测试,检查是否会抛出适当的异常,如果由于某种原因传递给此方法的参数恰好为空(假设它是某种验证异常)。

如果我尝试像上面的例子那样调用这个方法,IDE 会警告我将 null 传递给 @Nonnull... 但这正是我想要在这里做的。我可以使用 @SuppressWarnings("ConstantConditions") 注释调用或方法甚至测试类,但它会使代码混乱,并且我可能不会收到有关我在代码中犯的其他意外错误的警告。

所以问题是我是否可以在测试类中禁用对@Nonnull 的检查?或者我根本不应该对这些案例进行单元测试?

【问题讨论】:

  • @Nonnull 注释并不意味着总是为null 参数抛出NullPointerException。事实上,对于private 方法,我认为这样的要求是一种资源浪费,因为验证应该确保在编译时null 永远不会传递给该方法。因此 NPE 可能在通过 null 时作为操作的副作用出现,但显式测试应该已过时。
  • 好吧,假设这个方法是公开的。此外,在此方法的主体中,有时会抛出一些自定义 ValidationException,这对我来说可能很重要(对于回滚或类似的东西)。我已经编辑了问题。

标签: java unit-testing intellij-idea java-8 intellij-13


【解决方案1】:

如果您想针对错误情况测试代码行为,是否不可避免地要创建与被测代码规则有关的错误代码。如果 IDE 可以检查这些规则,显然,这些检查将检测到这一点,并且抑制这些警告是不可避免的。

与抑制警告一样,您应该尽量缩小应用抑制的代码范围。例如,您可以在测试代码中创建一个工厂方法,提供这样一个非法值,该值在基于类型系统的检查的雷达下飞行:

class IllegalValue {
    @SuppressWarnings("ConstantConditions")
    static @Nonnull <T> T sneakyNullReference() {
        return null;
    }
}

这样你就限制了对这个小单一方法的抑制。在您的测试用例中,您可以使用IllegalValue.sneakyNullReference() 来测试代码的null 行为而无需额外的抑制,因此在测试代码中的不适当位置使用null 时会得到正确的警告。为了清楚起见,我强烈建议不要将 sneakyNullReference() 的结果存储到变量中,但始终在需要的地方直接引用。

即在你的问题的测试中,代码应该是这样的

somethingSupplier.supply(IllegalValue.sneakyNullReference());

所以读者可以立即理解这里测试的内容……

【讨论】:

  • 这个主意不错,我试试,谢谢!
  • @mareckmareck:在 Java 8 下交换 @Nonnull&lt;T&gt; 的顺序应该是不必要的。我使用了这个顺序,因为将其视为类型注释而不是方法更有意义注释。
  • 你是对的......出于某种原因,IDEA 无法将其识别为正确的构造,即使代码编译得很好......
【解决方案2】:

很遗憾,您无能为力。忽略警告或添加抑制警告行。 intellij 可能有一个设置可以让您禁用警告,或者您可以在您不注意的窗口中打印警告,但这也不是一个很好的解决方案,因为这些选项将消除您可能想要的其他相关警告见。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    相关资源
    最近更新 更多