如果我为一个抛出一堆异常的函数编写测试用例,我应该在我的测试方法中为这些异常添加一个throws声明,还是应该捕获每个异常 . 这是怎样的正确方法?我相信try-catch是一种更好的方法,但是在catch块中我应该打印堆栈跟踪吗?
例如,我有一个抛出 AuthenticationException
的方法 getGroups(String name)
. 如果我写一个测试用例来检查 name
参数为空时是否抛出 IllegalArgumentException
,我该如何处理 AuthenticationException
?我是否将它添加到抛出我方法的一部分,或者我应该将异常包含在 try-catch
块中 .
@Test
public void testGetGroupsWithNull() throws AuthenticationException {
thrown.expect(IllegalArgumentException.class);
getGroups(null);
}
在上面的测试用例中我刚刚添加了一个 throws AuthenticationException
,但是我想知道是否最好将异常包含在try-catch块中以及在捕获异常后我做了什么 . 我可以打印堆栈跟踪 .
我通过不将它放在'throws'子句中而是放在try / catch块中来处理意外异常 AuthenticationException
.
@Test
public void testGetGroupsWithNull() {
thrown.expect(IllegalArgumentException.class);
try {
getGroups(null);
} catch(AuthenticationExcption e) {
Assert.fail("Authentication Exception");
}
}
5 回答
注释更具沟通性 .
它表示测试期望发生的事情,而不会强迫读者阅读代码 .
任何单个测试应该只期望抛出一个异常,因为每个测试应该测试单个行为 . 单个行为只能抛出一个异常 .
如果抛出任何其他异常,则表示测试失败 . 当然,测试方法签名必须反映任何可能的已检查异常,就像调用相同方法的实际代码一样 .
使用尽可能少的代码编写规则来解决问题,您的第一个代码段获胜 . 所以是的,将
AuthenticationException
放入测试方法的throws
子句中 . 它更简洁,更易读 .JUnit在这里有一篇很棒的文章:https://github.com/junit-team/junit/wiki/Exception-testing关于这个主题 . 你可以做:
要么:
如果JUnit测试引发意外异常,则失败 . 这就是你想要的行为 . 因此,使用try / catch块进行EVER没有意义 . 如果您期望发生异常,请使用ExpectedException规则(您可以从代码片段中明确了解该规则) . 但无论你是否期待,不要使用try / catch .
这意味着如果您的异常是已检查的异常,则需要throws子句 . 事实上,你不希望抛出异常,只是因为你的测试调用了一个可以SUSETIMES抛出一个已检查异常的方法 . 我养成了在每一种测试方法上编写
throws Exception
的习惯 . 没有理由不这样做;而且只需要担心一件事 .我只是在寻找同样的问题,因为我正在处理你的主题,我找到了单元测试最佳实践的一个很好的解释 . 从文章中略微提取可以帮助您 .
编写自己的catch块只是为了使测试失败,因为JUnit框架会为您处理这种情况 . 例如,假设您正在为以下方法编写单元测试:
这里我们有一个方法接受一个整数并返回一个整数,并在遇到错误时抛出IOException . 这是编写单元测试的错误方法,它确认方法在传递七时返回三:
测试中的方法指定它可以抛出IOException,这是一个经过检查的异常 . 因此,除非您捕获异常或声明测试方法可以传播异常,否则单元测试将无法编译 . 第二种选择是首选,因为它会导致更短,更集中的测试:
我们声明测试方法抛出异常而不是抛出IOException . 如果在调用测试方法期间发生任何异常,JUnit框架将确保此测试失败 - 不需要编写自己的异常处理 .
您可以在本文中找到有关JUnit最佳实践的更多信息:http://www.kyleblaney.com/junit-best-practices/
希望能有所帮助 .