关于单元测试:在Java中断言异常,如何?

Asserting exceptions in Java, how?

本问题已经有最佳答案,请猛点这里访问。

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

假设您有一个方法,如果给定某些条件,它将抛出一个数字格式异常。我想编写一个单元测试来检查异常是否被正确地授权。我怎样才能做到这一点?

另外,我正在使用JUnit编写单元测试。

谢谢。


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

1
@Test(expected=NumberFormatException.class);

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

1
2
3
4
5
6
try {
   formatNumber("notAnumber");
   fail("Expected NumberFormatException");
catch(NumberFormatException e) {
  // no-op (pass)
}


假设您使用的是JUnit4,那么在测试中调用方法的方式会导致它抛出异常,并使用JUnit注释

1
@Test(expected = NumberFormatException.class)

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@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();
  }
}

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

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


您可以这样做:

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

使用@test(应为ioexception.class)

http://junit.sourceforge.net/doc/faq/faq.htm测试

如果您有一个预期的异常,这是可以的。另一种策略是在测试方法的末尾添加assert.fail()。如果没有抛出异常,那么测试将相应失败。例如

1
2
3
4
5
@Test
public void testIOExceptionThrown() {      
   ftp.write(); // will throw IOException      
   fail();
}

在您的测试方法之前添加这个注释;它将完成这个技巧。

1
2
3
4
@Test(expected = java.lang.NumberFormatException.class)
public void testFooMethod() {
    // Add code that will throw a NumberFormatException
}


catch exception提供了一种不绑定到特定JUnit版本的解决方案,它克服了JUnit机制固有的一些缺点。