在Java中断言异常,如何? [复制]

Posted

技术标签:

【中文标题】在Java中断言异常,如何? [复制]【英文标题】:Asserting exceptions in Java, how? [duplicate] 【发布时间】:2011-05-02 03:21:55 【问题描述】:

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

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

附:我正在使用 JUnit 编写单元测试。

谢谢。

【问题讨论】:

【参考方案1】:

使用@Test(expected=IOException.class)

http://junit.sourceforge.net/doc/faq/faq.htm#tests_7

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

@Test
public void testIOExceptionThrown()       
   ftp.write(); // will throw IOException      
   fail();

【讨论】:

【参考方案2】:

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

@Test(expected=NumberFormatException.class);

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

try 
   formatNumber("notAnumber");
   fail("Expected NumberFormatException");
catch(NumberFormatException e) 
  // no-op (pass)

【讨论】:

当您想测试有关异常的事情时,这是一个很好的习惯用法,例如它的消息,而不仅仅是它的存在。 +1 - 关于旧版本的要点。 +1 - 如果没有第二个例子,这个问题的答案是不完整的。实际上,出于上述原因,我需要经常默认使用这种方法。 这样做的问题是,我看到很多人把样板文件弄乱了。 (即:忘记调用失败,或捕获过于笼统的异常)。就个人而言,我更喜欢创建一个采用 Runnable 或 Callable(用于检查的异常)并断言它抛出给定异常的方法。 (即:assertException(NumberFormatException.class, new Callable() ... formatNumber("notAnumber"); );。它只是样板文件,但“感觉更安全” @Michael D:您是否愿意详细说明您的评论并添加您自己的答案。我想你的想法。【参考方案3】:

假设您使用的是 JUnit 4,请在测试中以引发异常的方式调用该方法,并使用 JUnit 注释

@Test(expected = NumberFormatException.class)

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

【讨论】:

【参考方案4】:

You can do this:

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

【讨论】:

【参考方案5】:

在你的测试方法之前添加这个注解;它会成功的。

@Test(expected = java.lang.NumberFormatException.class)
public void testFooMethod() 
    // Add code that will throw a NumberFormatException

【讨论】:

【参考方案6】:

如果可以使用 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();
  

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

详情请参阅this article 和the ExpectedException JavaDoc

【讨论】:

为了深入推理和解释我想推荐这篇文章:monkeyisland.pl/2010/07/26/expected-exception-in-tests+1 from me。 @JonathanDrapeau 修复了链接。谢谢你告诉我!【参考方案7】:

catch-exception 提供了一个不绑定到特定 JUnit 版本的解决方案,该解决方案旨在克服 JUnit 机制中固有的一些缺点。

【讨论】:

以上是关于在Java中断言异常,如何? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Java 断言问题

Java Review(三十异常处理----补充:断言日志调试)

Java Review(三十异常处理----补充:断言日志调试)

什么时候用异常,什么时候用断言?

Java核心技术 卷Ⅰ 基础知识

断言后如何获取异常对象?