假设我有一个方法,其中某些参数使用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的检查?也许我根本不应该对这些案例进行单元测试?

最佳答案

如果要测试错误情况下的代码行为,是否不可避免地要创建关于被测试代码规则是错误的代码。如果IDE可以检查这些规则,那么显然,这些检查将检测到并不可避免地禁止显示这些警告。

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

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


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

即在测试您的问题的代码应该看起来像

somethingSupplier.supply(IllegalValue.sneakyNullReference());


因此,读者可以立即了解这里要进行的测试...

09-10 12:29
查看更多