如何测试没有引发异常?

我知道这样做的一个方法是:

@测试
公共图书馆{
试一试{
//执行您希望不会引发异常的代码。
}捕获(例外e){
失败(“不应引发任何异常”);
}
}

有没有更干净的方法?(可能使用Junit的@规则?)

你走错路了。只需测试您的功能:如果抛出异常,测试将自动失败。如果没有抛出异常,您的测试将全部显示为绿色

我注意到这个问题不时会引起人们的兴趣,所以我会稍微扩展一下

单元测试背景

当你做单元测试时,重要的是要给自己定义你认为是一个工作单位。基本上:对代码库的提取,可能包括也可能不包括表示单个功能的多个方法或类

或者,如单元测试的艺术,Roy Osherove第二版,第11页:

单元测试是一段自动化的代码,它调用被测试的工作单元,然后检查关于该单元单一最终结果的一些假设。单元测试几乎总是使用单元测试框架编写的。它可以很容易地编写,运行速度也很快。它是可信的、可读的和可维护的。只要生产代码没有改变,结果是一致的

重要的是要认识到,一个工作单元通常不仅仅是一种方法,但在最基本的层面上,它是一种方法,然后由其他工作单元封装

理想情况下,您应该为每个单独的工作单元都有一个测试方法,这样您就可以随时查看哪里出了问题。在本例中,有一个名为getUserById()的基本方法,它将返回一个用户,总共有3个工作单元

第一个工作单元应测试在输入有效和无效的情况下是否返回有效用户。
数据源抛出的任何异常都必须在这里处理:如果没有用户,那么应该有一个测试来证明在找不到用户时抛出异常。这方面的一个示例可能是IllegalArgumentException,它是通过@Test(expected=IllegalArgumentException.class)注释捕获的

一旦您处理了这个基本工作单元的所有用例,您就可以提高一个级别。在这里,您可以执行完全相同的操作,但只处理来自当前级别正下方的异常。这使您的测试代码保持良好的结构,并允许您快速运行整个体系结构以发现哪里出了问题,而不必到处乱跳

处理测试的有效和错误输入

现在应该清楚我们将如何处理这些异常。有两种类型的输入:有效的输入和错误的输入(严格意义上的输入是有效的,但不正确)

当您使用valid输入时,您正在设置隐式期望,即您编写的任何测试都将有效

这样的方法调用可以如下所示:existingUserById\u ShouldReturn\u UserObject。如果此方法失败(例如:抛出异常),则您知道出现了问题,可以开始挖掘

通过添加另一个测试(nonExistingUserById\u ShouldThrow\u IllegalArgumentException),该测试使用了错误的输入,并期望出现异常,您可以看到您的方法是否执行了错误输入的预期操作

TL;博士

在测试中,您试图做两件事:检查有效输入和错误输入。通过将其分为两种方法,每种方法只做一件事,您将有更清晰的测试,并且可以更好地了解哪里出了问题

通过记住分层的工作单元,您还可以减少对层次结构中较高的层所需的测试量,因为您不必考虑较低层中可能出现的每一个错误:当前层下面的层实际上可以保证您的依赖关系正常工作,如果出现问题错,它在当前层中(假设较低层本身没有抛出任何错误)

发表评论