java - junit 4测试怎么能断言某个异常被抛出呢?

  显示原文与译文双语对照的内容

如何使用JUnit4习惯用法测试某些代码引发异常?

虽然我可以这样做:


@Test
public void testFooThrowsIndexOutOfBoundsException() {
 boolean thrown = false;

 try {
 foo.doStuff();
 } catch (IndexOutOfBoundsException e) {
 thrown = true;
 }

 assertTrue(thrown);
}

在代表这些种类的situations,我回想一下,还有一种注释或者一个 Assert.xyz 或者 东西,则缺乏这种杂乱的) 最差的junit. in-the-spirit而

时间:

JUnit 4支持:


@Test(expected=IndexOutOfBoundsException.class)
public void testIndexOutOfBoundsException() {
 ArrayList emptyList = new ArrayList();
 Object o = emptyList.get(0);
}

如果你可以使用 JUnit 4.7,你可以使用 ExpectedException 规则


public class FooTest {
 @Rule
 public ExpectedException exception = ExpectedException.none();

 @Test
 public void doStuffThrowsIndexOutOfBoundsException() {
 Foo foo = new Foo();

 exception.expect(IndexOutOfBoundsException.class);
 foo.doStuff();
 }
}

这比这好得多 @Test(expected=IndexOutOfBoundsException.class) 由于 IndexOutOfBoundsExceptionfoo.doStuff() 之前被抛出,测试将失败

参见本文了解详细信息

在这个答案从 Rafal below, 编辑: 如果你正在使用 Java 8,look: http://stackoverflow.com 24621006/95725

在test,小心用预期的异常,因为它只宣称这个方法喷上去的异常,而不是特定的代码行.

我倾向于使用这个测试参数验证,因为这样的方法通常非常简单,但更复杂的测试可能会更好地提供:


try {
 methodThatShouldThrow();
 fail("My method didn't throw when I expected it to" );
} catch (MyException expectedException) {
}

应用判断。

为了解决同样的问题,我设置了一个小项目: http://code.google.com catch-exception/

使用这个小 helper 你会写


verifyException(foo, IndexOutOfBoundsException.class).doStuff();

这比 ExpectedException 4.7的规则要少得多。 skaffman提供的解决方案相比,你可以指定在哪一行代码中,你希望异常。 我希望这可以帮到你。

如何:捕捉一个非常普遍的异常,确保它将它移出Catch块,然后断言异常的类别是你期望的。 如果异常的类型是错误的,则这里断言将失败( 例如。 如果你得到了一个空指针( 而不是),则不会抛出异常。


public void testFooThrowsIndexOutOfBoundsException() {
 Throwable e = null;

 try {
 foo.doStuff();
 } catch (Throwable ex) {
 e = ex;
 }

 assertTrue(e instanceof IndexOutOfBoundsException);
}

BDD 样式解决方案: JUnit 4 + 捕获异常 + AssertJ


@Test
public void testFooThrowsIndexOutOfBoundsException() {

 when(foo).doStuff();

 then(caughtException()).isInstanceOf(IndexOutOfBoundsException.class);

}

源代码

依赖项


eu.codearte.catch-exception:catch-exception:1.3.3

你也可以这样做:


@Test
public void testFooThrowsIndexOutOfBoundsException() {
 try {
 foo.doStuff();
 assert false;
 } catch (IndexOutOfBoundsException e) {
 assert true;
 }
}

我在这里尝试了很多方法,但是它们要么复杂要么不完全符合我的需求。 事实上,你可以非常简单地编写 helper 方法:


public class ExceptionAssertions {
 public static void assertException(BlastContainer blastContainer ) {
 boolean caughtException = false;
 try {
 blastContainer.test();
 } catch( Exception e ) {
 caughtException = true;
 }
 if(!caughtException ) {
 throw new AssertionFailedError("exception expected to be thrown, but was not");
 }
 }
 public static interface BlastContainer {
 public void test() throws Exception;
 }
}

像这样使用:


assertException(new BlastContainer() {
 @Override
 public void test() throws Exception {
 doSomethingThatShouldExceptHere();
 }
});

零依赖:不需要 mockito,无需 powermock ;并且可以很好地使用 final 类。

...