如何在junit中处理异常

Sam*_*war 26 java junit unit-testing exception-handling exception

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*low 48

意外的异常是测试失败,因此您既不需要也不想捕获它.

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

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

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

@Test(expected=NullPointerException.class)
public void cannotConvertNulls() {
    service.convert(null);
}
Run Code Online (Sandbox Code Playgroud)

如果程序员懒惰并投掷Exception,或者他已经service返回0.0,则测试将失败.只有一个NPE会成功.请注意,预期异常的子类也有效.这对于NPEs 很少见,但与IOExceptions和SQLExceptions相同.

在极少数情况下,您要测试特定的异常消息,请使用新的ExpectedExceptionJUnit @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);
}
Run Code Online (Sandbox Code Playgroud)

现在,除非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);
}
Run Code Online (Sandbox Code Playgroud)

你可以内联testNumber; 现在,它没有多大帮助.您可以将其转换为参数化测试类.


Nat*_*hes 23

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

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

JUnit期望失败的测试会抛出异常,捕获它们只会阻止JUnit正确报告它们.这样,@ Test注释的预期属性也可以使用.


jav*_*per 7

您不需要捕获异常以使测试失败.只是放手(通过声明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
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用此类测试来验证您的代码是否正确验证输入并使用适当的异常处理无效输入.

  • ExpectedException 是测试预期异常的首选方法。 (3认同)

rag*_*era 5

您可以使用多种策略来处理测试中的预期异常。我认为上面已经提到了 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"));
}
Run Code Online (Sandbox Code Playgroud)

}

你可以这样做:

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

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

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