我编写了一个使用BufferedReader和FileReader的方法,结果是需要处理FileNotFoundException和IOException。
现在我已经在我的类中使用了try和catch语句来处理异常,所以没有问题。
我遇到的问题是编写一个测试,以验证是否已捕获异常。
我不能按如下方式编写测试,因为我的方法已捕获异常,因此它不会传播到测试中处理:
@Test(expected = FileNotFoundException.class)
public void testFileNotFound() {
...
};
我如何测试异常是否被捕获?我是否需要创建我的类的模拟对象并验证是否已使用Mockitio之类的东西捕获到异常?或者不创建模拟并使用Mockitio监视实际对象以验证是否已捕获异常?
编辑:这是我要测试的方法......public List<String[]> parse(String fileToRead) {
BufferedReader fileReader = null;
List<String[]> parsedData = new ArrayList<String[]>();
String currentLine;
try {
fileReader = new BufferedReader(new FileReader(fileToRead));
while ((currentLine = fileReader.readLine()) != null) {
String[] parsedLine = currentLine.split(",");
parsedData.add(parsedLine);
}
}
catch (FileNotFoundException e) {
logger.error("File does not exist", e);
}
return parsedData;
}
答案 0 :(得分:2)
我认为这是尝试反对语言的经典例子,而不是使用它。它也可能是代码的一个例子,它不能通过设计进行测试。
首先,理解已检查和未检查的异常之间的概念区别非常重要。未经检查的例外情况如NullPointerException
和ArrayIndexOutOfBoundsException
是&#34;未选中&#34; (意思是编译器并不关心它们),因为当它们被抛出时,通常是程序员的错。在方法调用之前使用if语句通常可以轻松防止这些异常。另一方面,IOException
和FileNotFoundException
被检查&#34; (意味着编译器会抱怨缺少catch / throw),因为即使您在尝试读取文件之前检查文件是否存在File#exists()
方法,同时也可能发生外部事件导致文件丢失,或者当您正在读取其上的文件时,可能会从机器中拔出硬盘。检查异常通常表示一种崩溃状态,您必须专门决定如何从中恢复,并且只有您(作为程序员)才能做出决定。
考虑你的方法。如何通过方法的输出来判断读取操作是否失败或是否为空文件?你不能,因为即使这两个事件完全不同,你也会以完全相同的方式处理它们。这可能是您想要的,也可能不是,但处理这两种情况可能与您调用该方法的方式不同。例如,您可能希望向用户显示一条消息&#34;文件为空&#34;或者那个&#34;文件不存在&#34;而不是&#34;没有数据&#34;。
其次,可测试性问题(可能是也可能不是问题,具体取决于您的设置)。在catch
- 子句中发生的唯一事情(因此是抛出和捕获异常的唯一指示)是臭名昭着的记录和忘记&#34;战略。您正在记录错误(而不是在适当的情况下处理/响应它),因此要验证是否捕获了异常,您唯一真正的选择是模拟记录器(如果您的设计允许)并验证其error()
方法被称为。如果您的目标是验证在给定某个输入时抛出异常,则您无法检查输出,因为这只是验证输出 - 完全不同的测试。您必须检查抛出异常产生的代码路径,在这种情况下,一种方法是模拟记录器。