问题
我如何通过惯用方式使用JUnit4来测试某些代码是否会抛出异常?
虽然我当然可以做这样的事情:
@Test
public void testFooThrowsIndexOutOfBoundsException() {
boolean thrown = false;
try {
foo.doStuff();
} catch (IndexOutOfBoundsException e) {
thrown = true;
}
assertTrue(thrown);
}
我记得有一个注释或一个Assert.xyz orsomething,它远不那么愚蠢,而且在这种情况下更有JUnit的精神。
#1 热门回答(1897 赞)
JUnit 4支持这一点:
@Test(expected = IndexOutOfBoundsException.class)
public void testIndexOutOfBoundsException() {
ArrayList emptyList = new ArrayList();
Object o = emptyList.get(0);
}
参考:https://junit.org/junit4/faq.html#atests_7
#2 热门回答(1153 赞)
编辑现在JUnit5已经发布,最好的选择是使用Assertions.assertThrows()
(见my other answer)。
如果您尚未迁移到JUnit 5,但可以使用JUnit 4.7,则可以使用ExpectedException
规则:
public class FooTest {
@Rule
public final ExpectedException exception = ExpectedException.none();
@Test
public void doStuffThrowsIndexOutOfBoundsException() {
Foo foo = new Foo();
exception.expect(IndexOutOfBoundsException.class);
foo.doStuff();
}
}
这比@Test(expected = IndexOutOfBoundsException.class)
好得多,因为如果在foo.doStuff()之前抛出
IndexOutOfBoundsException`,测试将会失败。
详情请参阅49068052
#3 热门回答(401 赞)
小心使用预期的异常,因为它只声称方法在该测试中引发该异常,而不是a特定代码行。
我倾向于使用它来测试参数验证,因为这些方法通常非常简单,但更复杂的测试可能更适合于:
try {
methodThatShouldThrow();
fail( "My method didn't throw when I expected it to" );
} catch (MyException expectedException) {
}
应用判断。