如何使用JUnit来测试某些代码是否抛出异常?

我当然可以这样做:

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

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

  assertTrue(thrown);
}

我记得,对于这类情况,有一个注释或Assert.xyz之类的东西远没有JUnit那么笨拙,更符合JUnit的精神。


当前回答

我建议库assertj核心处理junit测试中的异常

在java 8中,如下所示:

//given

//when
Throwable throwable = catchThrowable(() -> anyService.anyMethod(object));

//then
AnyException anyException = (AnyException) throwable;
assertThat(anyException.getMessage()).isEqualTo("........");
assertThat(exception.getCode()).isEqualTo(".......);

其他回答

小心使用预期的异常,因为它只断言方法抛出了该异常,而不是测试中的特定代码行。

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

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

应用判断。

有两种编写测试用例的方法

使用方法引发的异常来注释测试。类似于@Test(预期=IndexOutOfBoundsException.class)您可以使用try-catch块在测试类中捕获异常,并对从测试类中的方法抛出的消息进行断言。尝试{}catch(从方法e抛出的异常){assertEquals(“message”,即getmessage());}

我希望这能回答你的问题快乐学习。。。

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

使用这个小助手,您可以编写

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

这比JUnit 4.7的ExpectedException规则更详细。与skaffman提供的解决方案相比,您可以指定期望在哪行代码中出现异常。我希望这有帮助。

这取决于JUnit版本和使用的断言库。

JUnit5和4.13见答案如果您使用AssertJ或google truth,请参阅答案

JUnit<=4.12的原始答案是:

    @Test(expected = IndexOutOfBoundsException.class)
    public void testIndexOutOfBoundsException() {

        ArrayList emptyList = new ArrayList();
        Object o = emptyList.get(0);

    }

尽管答案对于JUnit<=4.12有更多选项。

参考:

JUnit测试常见问题解答

如前所述,JUnit中有许多处理异常的方法。但在Java8中还有另一个:使用Lambda表达式。使用Lambda表达式,我们可以实现如下语法:

@Test
public void verifiesTypeAndMessage() {
    assertThrown(new DummyService()::someMethod)
            .isInstanceOf(RuntimeException.class)
            .hasMessage("Runtime exception occurred")
            .hasMessageStartingWith("Runtime")
            .hasMessageEndingWith("occurred")
            .hasMessageContaining("exception")
            .hasNoCause();
}

assertThrown接受一个函数接口,它的实例可以用lambda表达式、方法引用或构造函数引用创建。assertThrown接受该接口将期望并准备好处理异常。

这是一种相对简单但功能强大的技术。

看看这篇描述这一技巧的博文:http://blog.codeleak.pl/2014/07/junit-testing-exception-with-java-8-and-lambda-expressions.html

源代码可在此处找到:https://github.com/kolorobot/unit-testing-demo/tree/master/src/test/java/com/github/kolorobot/exceptions/java8

披露:我是博客和项目的作者。