Aar*_*lla 7 java unit-testing exception nullpointerexception non-nullable
我有一个像这样的方法:
public void foo(@Nonnull String value) {...}
Run Code Online (Sandbox Code Playgroud)
我想编写一个单元测试,以确保foo()当抛出NPE value是null,但我不能,因为编译器拒绝当IDE启用静态空指针流分析编译单元测试.
如何使此测试编译(在Eclipse中启用"启用基于注释的空分析"):
@Test(expected = NullPointerException.class)
public void test() {
T inst = ...
inst.foo(null);
}
Run Code Online (Sandbox Code Playgroud)
注意:理论上,编译器的静态空指针应该阻止这样的情况.但是没有什么能阻止某人在关闭静态流分析的情况下编写另一个模块并调用该方法null.
常见情况:没有流量分析的大杂乱旧项目.我首先注释一些实用程序模块.在这种情况下,我只好现有或新的单元测试,其检查代码的行为对所有模块不使用流量分析还.
我的猜测是,我必须将这些测试移动到一个未经检查的模块中,并在我进行流量分析时移动它们.这将有效并且符合哲学,但这将是很多手工工作.
换句话说:我不能轻易编写一个测试,上面写着"当代码无法编译时成功"(我必须将代码片放入文件中,从单元测试中调用编译器,检查输出是否有错误. .. 不漂亮).那么如何在调用者忽略时轻松测试代码失败@Nonnull?
隐藏null在一个方法中可以解决问题:
public void foo(@NonNull String bar) {
Objects.requireNonNull(bar);
}
/** Trick the Java flow analysis to allow passing <code>null</code>
* for @Nonnull parameters.
*/
@SuppressWarnings("null")
public static <T> T giveNull() {
return null;
}
@Test(expected = NullPointerException.class)
public void testFoo() {
foo(giveNull());
}
Run Code Online (Sandbox Code Playgroud)
以上编译很好(是的,双重检查 - 当使用foo(null)我的IDE给我一个编译错误 - 所以"启用""检查").
与通过注释给出的解决方案相比,上面具有适用于任何类型的参数类型的良好副作用(但可能需要Java8始终使类型推断正确).
是的,测试通过(如上所述),并在注释掉Objects.requireNonNull()线时失败.