是否在预期的异常发生时通过了测试? 如果出现意外异常,它是否应该通过测试? 处理异常是多余的,因为它不能通过测试,因此可以作为测试吗?
答案 0 :(得分:11)
您必须添加具有预期异常的expected
属性,因此如果抛出指定的异常,测试将通过。否则,它将失败。
例如:
@Test(expected=NullPointerException.class)
public void cannotConvertNulls() {
service.convert(null);
}
...或
@Test(expected = ArithmeticException.class)
public void divisionWithException() {
int i = 1/0;
}
Test annotation支持两个可选参数。首先, 预期,声明测试方法应抛出异常。如果它 不抛出异常或抛出不同的异常 宣布的那个,测试失败了。
只是为了让您知道,您还可以测试超时。
第二个可选参数timeout会导致测试失败 花费的时间超过指定的时钟时间(以 毫秒)。以下测试失败:
@Test(timeout=100)
public void infinity() {
while(true);
}
希望能提供帮助
答案 1 :(得分:2)
对于预期的异常,使用JUnit有很好的方法:
@Test(expected=NullPointerException.class)
public void testNullPointerExceptionIsThrown() {
ArrayList emptyList;
emptyList.size(); //or add, remove etc.
}
JUnit中的上述测试将传递,因为它是使用@Test注释声明的,测试方法应该期望抛出空指针异常。
答案 2 :(得分:1)
如果测试期望某些数据会出现特定异常,那么是,如果抛出该特定异常,则传递。
如果测试期望某些数据出现特定异常,或没有异常预期,那么是,它应该失败如果抛出任何超出预期的异常。
不要自己处理抛出的异常,除非你必须(如果必须,那是一种测试气味 - 重新审视你处理异常的原因)。向JUnit指出您期望异常的最佳方法是使用expected
注释上的@Test
字段。
例如,假设您正在测试一个罗马数字转换器,并说任何不在正常罗马数字中的东西都是非法参数(即P)。
@Test(expected = IllegalArgumentException.class)
public void method_takesIllegalArgument_throwsIllegalArgumentException() {
convertRomanNumeralToNumber("PXL");
}
答案 3 :(得分:0)
例外是API的一部分,有时也是明确的。因此,您应该记录代码可能抛出的异常,并编写测试以确保它们得到维护。
@Test(expected = ThisException.class)
是一个很好的起点,如果你有JUnit4并且正在编写一个throw new ThisException(...)
的方法。请注意选择最合适的例外的值:如果您变得懒惰并使用expected = Exception.class
,那么如果您更改为throw new ThatException(...)
,您的代码会接受它。当且仅当没有抛出异常(JUnit将为您强制执行)时,您的非异常代码才会通过,并且您的测试应该仔细指定预期的异常,以便当且仅当抛出该特定异常时它们才会失败。 / p>
作为评论中提到的dhiller,ExpectedException rule也是JUnit4的一个非常好的选择,并允许进一步检查抛出的异常:
@Rule ExpectedException expectedException = ExpectedException.none();
@Test public void yourTest() {
// This is for demonstration. Don't actually verify the exact exception message
// unless you want to have to update your test if the text ever changes.
expectedException.expectMessage("Error 743: Toilet paper missing.");
systemUnderTest.doStuff();
}
但是如果你真的想在捕获异常后检查状态,最好的方法是JUnit3风格:
@Test public void yourTest() {
try {
systemUnderTest.doStuff();
fail("ThisException expected.");
} catch (ThisException expected) {
assertEquals(743, expected.getErrorNumber());
}
// In both @Test(expected=...) and ExpectedException code, the
// exception-throwing line will be the last executed line, because Java will
// still traverse the call stack until it reaches a try block--which will be
// inside the JUnit framework in those cases. The only way to prevent this
// behavior is to use your own try block.
// This is especially useful to test the state of the system after the
// exception is caught.
assertFalse(systemUnderTest.hasToiletPaper());
}
另一个声称在此帮助的图书馆是catch-exception;但是,截至2014年5月,该项目似乎处于维护模式(由Java 8淘汰),而且很像Mockito catch-exception只能操纵非final
方法。