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

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

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

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

谢谢。

【问题讨论】:

    标签: java unit-testing exception-handling 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

            【讨论】:

            【解决方案7】:

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

            【讨论】:

              猜你喜欢
              • 2010-09-29
              • 2023-03-15
              • 2012-08-28
              • 2020-03-22
              • 2018-11-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多