Intellij IDEA在单元测试中警告@Nonnull注释

mar*_*eck 2 java unit-testing intellij-idea java-8 intellij-13

假设我有一个方法,其中一些参数用javax @Nonnull注释注释.

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

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

somethingSupplier.supply(null);
Run Code Online (Sandbox Code Playgroud)

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

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

所以问题是我是否能以某种方式禁用测试类中对@Nonnull的检查?或许我不应该对这些案件进行单元测试?

Hol*_*ger 5

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

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

class IllegalValue {
    @SuppressWarnings("ConstantConditions")
    static @Nonnull <T> T sneakyNullReference() {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

somethingSupplier.supply(IllegalValue.sneakyNullReference());
Run Code Online (Sandbox Code Playgroud)

所以读者立即明白这里测试的内容......

  • @mareckmareck:在 Java 8 下不需要交换 `@Nonnull` 和 `&lt;T&gt;` 的顺序。我使用这个顺序是因为将其视为类型注释而不是方法注释更有意义。 (2认同)