【问题标题】:how to handle exceptions in junitjunit如何处理异常
【发布时间】:2013-05-11 21:02:20
【问题描述】:

我写了一些测试用例来测试一些方法。但是有些方法会抛出异常。我做得对吗?

private void testNumber(String word, int number) {
    try {
        assertEquals(word,  service.convert(number));
    } catch (OutOfRangeNumberException e) {
        Assert.fail("Test failed : " + e.getMessage());
    }
}

@Test
public final void testZero() {
    testNumber("zero", 0);
}

如果我通过-45,它将失败并显示OutOfRangeException,但我无法测试特定异常,例如@Test(Expected...)

【问题讨论】:

    标签: java unit-testing exception junit exception-handling


    【解决方案1】:

    意外异常是测试失败,因此您既不需要也不想捕获一个异常。

    @Test
    public void canConvertStringsToDecimals() {
        String str = "1.234";
        Assert.assertEquals(1.234, service.convert(str), 1.0e-4);
    }
    

    直到service 没有抛出IllegalArgumentException,因为str 中有一个小数点,这将是一个简单的测试失败。

    应由@Test 的可选expected 参数处理预期的异常。

    @Test(expected=NullPointerException.class)
    public void cannotConvertNulls() {
        service.convert(null);
    }
    

    如果程序员很懒,扔了Exception,或者如果他有service返回0.0,测试就会失败。只有NPE 会成功。请注意,预期异常的子类也可以工作。这在NPEs 中很少见,但在IOExceptions 和SQLExceptions 中很常见。

    在您想要测试特定异常消息的极少数情况下,您可以使用新的ExpectedException JUnit @Rule

    @Rule
    public ExpectedException thrown= ExpectedException.none();
    @Test
    public void messageIncludesErrantTemperature() {
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage("-400"); // Tests that the message contains -400.
        temperatureGauge.setTemperature(-400);
    }
    

    现在,除非 setTemperature 抛出 IAE 并且消息包含用户尝试设置的温度,否则测试将失败。此规则可以以更复杂的方式使用。


    您的示例最好由以下人员处理:

    private void testNumber(String word, int number)
            throws OutOfRangeNumberException {
        assertEquals(word,  service.convert(number));
    }
    
    @Test
    public final void testZero()
            throws OutOfRangeNumberException {
        testNumber("zero", 0);
    }
    

    你可以内联testNumber;现在,它没有多大帮助。你可以把它变成一个参数化的测试类。

    【讨论】:

      【解决方案2】:

      删除 try-catch 块并将throws Exception 添加到您的测试方法中,例如:

      @Test
      public final void testZero() throws Exception {
          assertEquals("zero",  service.convert(0));
      }
      

      JUnit 期望失败的测试会抛出异常,你捕获它们只是阻止 JUnit 能够正确报告它们。这样@Test 注释上的预期属性也将起作用。

      【讨论】:

        【解决方案3】:

        您无需捕获异常即可使测试失败。放手(通过声明throws)无论如何它都会失败。

        另一种情况是,当您实际预期异常时,您将失败放在 try 块的末尾。

        例如:

        @Test
        public void testInvalidNumber() {
          try {
              String dummy = service.convert(-1));
              Assert.fail("Fail! Method was expected to throw an exception because negative numbers are not supported.")
          } catch (OutOfRangeException e) {
              // expected
          }
        }
        

        您可以使用这种测试来验证您的代码是否正确验证输入并处理无效输入并出现适当的异常。

        【讨论】:

        • ExpectedException 是测试预期异常的首选方法。
        • 如果你需要检查异常的结构,你只需要ExpectedException。例如,CmisExceptions 应该在其中设置特定的故障原因。我必须编写测试来检查这一点,为此我使用了 Hamcrest 匹配器。如果您只是期望出现异常,请使用 @Test 的参数。
        【解决方案4】:

        您可以使用多种策略来处理测试中的预期异常。我认为上面已经提到了 JUnit 注释和 try/catch 成语。我想提请注意 Lambda 表达式的 Java 8 选项。

        例如给定:

        class DummyService {
        public void someMethod() {
            throw new RuntimeException("Runtime exception occurred");
        }
        
        public void someOtherMethod(boolean b) {
            throw new RuntimeException("Runtime exception occurred",
                    new IllegalStateException("Illegal state"));
        }
        

        }

        你可以这样做:

        @Test
        public void verifiesCauseType() {
            // lambda expression
            assertThrown(() -> new DummyService().someOtherMethod(true))
                    // assertions
                    .isInstanceOf(RuntimeException.class)
                    .hasMessage("Runtime exception occurred")
                    .hasCauseInstanceOf(IllegalStateException.class);
        }
        

        看看这个博客,它通过示例涵盖了大多数选项。

        http://blog.codeleak.pl/2013/07/3-ways-of-handling-exceptions-in-junit.html

        这个更全面地解释了 Java 8 Lambda 选项:

        http://blog.codeleak.pl/2014/07/junit-testing-exception-with-java-8-and-lambda-expressions.html

        【讨论】:

          猜你喜欢
          • 2016-04-13
          • 2021-12-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多