我有一个方法,有时会抛出异常:
this.items[index] = element;
我有一个单元测试,它断言应该抛出的异常实际上已经抛出:
try
{
doSomethingWithIndex(-1);
Assert.fail("should cause exception");
}
catch (IndexOutOfBoundsException expected)
{
Assert.assertNotNull(expected.getMessage());
}
此测试作为连续构建的一部分运行,有时会失败,因为getMessage()实际上返回null。为什么会发生这种情况?我的代码永远不会抛出带有null消息的异常。
编辑
我最初的代码示例具有误导性,抛出的异常实际上来自于直接索引数组。不过,我可以使用自定义抛出的异常来重现相同的行为。
我添加了建议的代码:
catch (IndexOutOfBoundsException expected)
{
if (expected.getMessage() == null)
{
expected.printStackTrace();
}
Assert.assertNotNull(expected.getMessage());
}
控制台输出除了原因之外,还缺少堆栈跟踪。以下是完整的输出:
java.lang.ArrayIndexOutOfBoundsException
找到了类似问题的答案。
JIT编译器将在某些异常中优化掉堆栈跟踪,如果它们发生得足够多的话。
JVM标志-XX:-OmitStackTraceInFastThrow防止了这种行为,并且似乎修复了闪烁的单元测试。
当异常具有null消息时,尝试打印异常的堆栈跟踪。可能是其他代码抛出的,就像您实际访问过去的数组长度一样。
您写道:"我的代码永远不会抛出带有空消息的异常"
你在第三方图书馆吗?我认为标准的java代码从来不会抛出像上面这样的异常,但一些pourly编码的jar…:)