在Java中断言异常,如何?

nun*_*nos 12 java junit unit-testing exception-handling

这可能是一个概念上愚蠢的问题,但也可能不是,因为我还是学生,我想我应该没问题.

想象一下,你有一个方法,如果给定某些条件,它将抛出一个NumberFormatException.我想编写一个单元测试来查看异常是否正确.我怎样才能做到这一点?

PS我正在使用JUnit编写单元测试.

谢谢.

Mic*_*l D 30

正如其他海报所建议的,如果您使用的是JUnit4,那么您可以使用注释:

@Test(expected=NumberFormatException.class);
Run Code Online (Sandbox Code Playgroud)

但是,如果您使用的是旧版本的JUnit,或者您想在同一测试方法中执行多个"异常"断言,则标准惯用法是:

try {
   formatNumber("notAnumber");
   fail("Expected NumberFormatException");
catch(NumberFormatException e) {
  // no-op (pass)
}
Run Code Online (Sandbox Code Playgroud)

  • 这样做的问题在于,我看到很多人搞砸了样板.(即:忘记调用失败,或者过于笼统的异常).就个人而言,我更喜欢创建一个采用Runnable或Callable(对于已检查的异常)并声明它抛出给定异常的方法.(即:assertException(NumberFormatException.class,new Callable <Void>(){... formatNumber("notAnumber");});.它和样板一样多,但"感觉更安全" (3认同)
  • @Michael D:您是否愿意详细说明您的评论,并可能添加您自己的答案.我想像你的想法. (2认同)

Fea*_*nor 10

假设您正在使用JUnit 4,请以导致它抛出异常的方式调用测试中的方法,并使用JUnit注释

@Test(expected = NumberFormatException.class)
Run Code Online (Sandbox Code Playgroud)

如果抛出异常,测试将通过.


Nam*_*ter 8

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

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

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

    exception.expect(IndexOutOfBoundsException.class);
    exception.expectMessage("happened?");
    exception.expectMessage(startsWith("What"));
    foo.doStuff();
  }
}
Run Code Online (Sandbox Code Playgroud)

这比@Test(expected=IndexOutOfBoundsException.class)因为如果IndexOutOfBoundsException之前抛出测试将会失败要好得多foo.doStuff()

有关详细信息,请参阅本文ExpectedException JavaDoc