Java 在junit中如何处理异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16596418/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to handle exceptions in junit
提问by Sammy Pawar
I wrote some test cases to test some method. But some methods throw an exception. Am I doing it correctly?
我写了一些测试用例来测试一些方法。但是有些方法会抛出异常。我做得对吗?
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);
}
If I pass -45
, it will fail with OutOfRangeException
but I am not able to test specific exception like @Test(Expected...)
如果我通过-45
,它将失败,OutOfRangeException
但我无法测试特定的异常,例如@Test(Expected...)
回答by javadeveloper
You don't need to catch the exception to fail the test. Just let it go (by declaring throws
) and it will fail anyway.
您无需捕获异常即可使测试失败。放手吧(通过声明throws
)它无论如何都会失败。
Another case is when you actually expect the exception, then you put fail at the end of try block.
另一种情况是当您实际上期望异常时,然后将失败放在 try 块的末尾。
For example:
例如:
@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
}
}
You can use this kind of test to verify if your code is properly validating input and handles invalid input with a proper exception.
您可以使用这种测试来验证您的代码是否正确验证输入并处理具有适当异常的无效输入。
回答by Nathan Hughes
Remove the try-catch block and add throws Exception
to your test method, like:
删除 try-catch 块并添加throws Exception
到您的测试方法中,例如:
@Test
public final void testZero() throws Exception {
assertEquals("zero", service.convert(0));
}
JUnit expects failing tests will throw Exceptions, your catching them is just stopping JUnit from being able to report them properly. Also this way the expected property on the @Test annotation will work.
JUnit 期望失败的测试会抛出异常,您捕获它们只是阻止 JUnit 能够正确报告它们。同样,@Test 注释上的预期属性也将起作用。
回答by Eric Jablow
An unexpected exception is a test failure, so you neither need nor want to catch one.
意外异常是测试失败,因此您既不需要也不想捕获异常。
@Test
public void canConvertStringsToDecimals() {
String str = "1.234";
Assert.assertEquals(1.234, service.convert(str), 1.0e-4);
}
Until service
does not throw an IllegalArgumentException
because str
has a decimal point in it, that will be a simple test failure.
直到service
不抛出IllegalArgumentException
因为其中str
有小数点,这将是一个简单的测试失败。
An expected exception should be handled by the optional expected
argument of @Test
.
预期的异常应由 的可选expected
参数处理@Test
。
@Test(expected=NullPointerException.class)
public void cannotConvertNulls() {
service.convert(null);
}
If the programmer was lazy and threw Exception
, or if he had service
return 0.0
, the test will fail. Only an NPE
will succeed. Note that subclasses of the expected exception also work. That's rare for NPE
s, but common with IOException
s and SQLException
s.
如果程序员偷懒扔了Exception
,或者他有service
return 0.0
,测试就会失败。只有一个NPE
会成功。请注意,预期异常的子类也有效。这对NPE
s 来说很少见,但在IOException
s 和SQLException
s 中很常见。
In the rare case that you want to test for a specific exception message, you use the newish ExpectedException
JUnit @Rule
.
在您想要测试特定异常消息的极少数情况下,您可以使用新的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);
}
Now, unless the setTemperature throws an IAE
and the message contains the temperature the user was trying to set, the test fails. This rule can be used in more sophisticated ways.
现在,除非 setTemperature 抛出 anIAE
并且消息包含用户尝试设置的温度,否则测试将失败。可以以更复杂的方式使用此规则。
Your example can best be handled by:
您的示例最好通过以下方式处理:
private void testNumber(String word, int number)
throws OutOfRangeNumberException {
assertEquals(word, service.convert(number));
}
@Test
public final void testZero()
throws OutOfRangeNumberException {
testNumber("zero", 0);
}
You can inline testNumber
; now, it does not help much. You can turn this into a parametrized test class.
你可以内联testNumber
; 现在,它没有多大帮助。你可以把它变成一个参数化的测试类。
回答by raghera
There are several strategies that are open to you to deal with expected exceptions in your tests. I think the JUnit annotations and try/catch idiom have already been mentioned above. I'd like to draw attention to the Java 8 option of Lambda expressions.
您可以使用多种策略来处理测试中的预期异常。我认为上面已经提到了 JUnit 注释和 try/catch 习惯用法。我想提请注意 Lambda 表达式的 Java 8 选项。
For instance given:
例如给出:
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"));
}
}
}
You can do this:
你可以这样做:
@Test
public void verifiesCauseType() {
// lambda expression
assertThrown(() -> new DummyService().someOtherMethod(true))
// assertions
.isInstanceOf(RuntimeException.class)
.hasMessage("Runtime exception occurred")
.hasCauseInstanceOf(IllegalStateException.class);
}
Take a look at this blog which covers most of the options with examples.
看看这个博客,它涵盖了大多数选项和示例。
http://blog.codeleak.pl/2013/07/3-ways-of-handling-exceptions-in-junit.html
http://blog.codeleak.pl/2013/07/3-ways-of-handling-exceptions-in-junit.html
And this one explains the Java 8 Lambda option more fully:
这篇文章更全面地解释了 Java 8 Lambda 选项:
http://blog.codeleak.pl/2014/07/junit-testing-exception-with-java-8-and-lambda-expressions.html
http://blog.codeleak.pl/2014/07/junit-testing-exception-with-java-8-and-lambda-expressions.html