如何在junit中处理exception

我写了一些测试用例来测试一些方法。 但是有些方法会抛出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); } 

如果我传递-45 ,它将失败并出现OutOfRangeException但我无法测试特定的exception,如@Test(Expected...)

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

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

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

预期的exception应该由@Test的可选expected参数处理。

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

如果程序员懒惰并抛出Exception ,或者他的service返回0.0 ,则测试将失败。 只有NPE才能成功。 请注意,预期exception的子类也有效。 这对于NPE很少见,但与IOExceptionSQLException

在极少数情况下,您要测试特定的exception消息,请使用新的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 ; 现在,它没有多大帮助。 您可以将其转换为参数化测试类。

删除try-catch块并向测试方法添加throws Exception ,如:

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

JUnit期望失败的测试将抛出exception,捕获它们只是阻止JUnit能够正确报告它们。 这样,@ Test注释的预期属性也可以使用。

您不需要捕获exception以使测试失败。 只是放手(通过宣布throws )它无论如何都会失败。

另一种情况是,当您实际期望exception时,则在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 } } 

您可以使用此类测试来validation您的代码是否正确validation输入并使用适当的exception处理无效输入。

您可以使用几种策略来处理测试中的预期exception。 我认为上面已经提到过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