我正在Java项目的类路径中读取一个文件。
示例代码:
public static Properties loadPropertyFile(String fileName) {
Properties properties = new Properties();
InputStream inputStream = PropertyReader.class.getClassLoader().getResourceAsStream(fileName);
if (inputStream != null) {
try {
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
} else {
throw new Exception("Property file: [" + fileName + "] not found in the classpath");
}
return properties;
}
工作正常。我正在为此代码编写Junit测试。如何在IOException
中为properties.load(inputStream)
创建方案?
我应该在properties.file中添加哪些值来获取IOException
?
答案 0 :(得分:1)
当您查看Properties::load
的实现时,您会发现该类从不显式抛出异常。触发IOException
的唯一方法是在调用输入流的InputStream
方法时发出引发此异常的read
。
您是否可以控制PropertyReader
班级?模拟此错误的一种方法是instrument this class loader为给定的InputStream
测试值返回错误fileName
以抛出IOException
。或者,您可以通过将签名更改为:
public static Properties loadPropertyFile(String fileName) {
return loadPropertyFile(fileName, PropertyReader.class);
}
public static Properties loadPropertyFile(String fileName, ClassLoader cl) {
// your code...
}
处理类加载器:
class TestLoader extends ClassLoader {
@Override
public InputStream getResourceAsStream() {
return new InputStream() {
@Override
public byte read() throws IOException {
throws new IOException();
}
}
}
}
您不能将特定字符添加到导致IOException
的属性文件中,因为InputStream
只读取字节。任何编码问题都将导致IllegalArgumentException
。
答案 1 :(得分:1)
下面的代码为我复制了例外。
import java.io.*;
import java.util.*;
public class Test {
public static void main(String[] args) throws Exception
{
Properties properties = new Properties();
File f = new File(args[0]);
InputStream inputStream = new FileInputStream(f);
inputStream.mark(0);
inputStream.reset();
if (inputStream != null) {
try {
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
} else {
throw new Exception("Property file: [" + args[0] + "] not found in the classpath");
}
}
}
输出:
java Test a.txt
Exception in thread "main" java.io.IOException: mark/reset not supported
at java.io.InputStream.reset(InputStream.java:347)
at Test.main(Test.java:16)
答案 2 :(得分:1)
你考虑过一个模拟框架吗?模拟属性的new
运算符以返回在调用IOException
方法时抛出load
的模拟实现。
mockitio和powermockito将允许你这样做。
答案 3 :(得分:0)
强制load
调用抛出IOException
的一种方法是传递一个封闭的流。如果你可以重构你的方法来接受InputStream
,你可以将一个封闭的流传递给方法并检查它是否抛出异常。
那就是说,单元测试应该涵盖你编写的代码。在我看来,如果输入流有错误,您正在测试load
是否抛出异常。这是多余的。
答案 4 :(得分:-2)
空或fileName
参数无效。
答案 5 :(得分:-2)
传递一个空白字符串作为文件名