我正在尝试测试一个进行文件/流处理的类。例如,方法readFile
将使用BufferedReader
返回ArrayList
字符串,其中包含文件的每一行:
public ArrayList<String> readFile(String fileName)
{
ArrayList<String> result = new ArrayList<String>();
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader(STORAGE_DIRECTORY+fileName);
br = new BufferedReader(fr);
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
result.add(sCurrentLine);
}
}
catch (FileNotFoundException e) {
return new ArrayList<String>();
} catch (IOException e) {
return new ArrayList<String>();
}
br.close();
fr.close();
return result;
}
但是当我使用Mockito来模拟bufferedReader
方法“readLine()”时,由于FileNotFoundException
构造函数而抛出FileReader
。我必须使用temporaryFile
或模拟FileReader
构造函数吗?
@Test
public void readFileTest5() throws Exception {
BufferedReader bufferedReader = Mockito.mock(BufferedReader.class);
FileReader fileReader = Mockito.mock(FileReader.class);
when(BufferedReader.readLine()).thenReturn("abc");
assertEquals("",new ArrayList<String>(), FileUtil.readFile("abc"));
}
谢谢
答案 0 :(得分:3)
在readFile
BufferedReader
换行FileReader
和FileReader
内创建该方法,这样您就没有机会模仿FileReader
这意味着您无法模拟BufferedReader
实例中的输入。
这种方法使测试变得困难。
我建议改变你的做法。例如:
public ArrayList<String> readFile(BufferedReader reader) {
// ...
}
然后你的测试可能是:
@Test
public void readFileTest() throws Exception {
BufferedReader bufferedReader = Mockito.mock(BufferedReader.class);
Mockito.when(bufferedReader.readLine()).thenReturn("a", "b", "c", null);
List<String> expected = Arrays.asList("a", "b", "c");
Assert.assertEquals("", expected, readFile(bufferedReader));
}
或者根本没有Mockito:
@Test
public void readFileTest() throws Exception {
BufferedReader bufferedReader = new BufferedReader(new StringReader("a\nb\nc"));
List<String> expected = Arrays.asList("a", "b", "c");
Assert.assertEquals("", expected, readFile(bufferedReader));
}
另一种方法是创建一个实际的文件并读取它,即不需要嘲笑任何东西。您可以使用JUnit的Temporary Folder Rule来帮助在测试后进行清理。
另请注意:readFile()
未安全关闭BufferedReader
和FileReader
。
答案 1 :(得分:1)
由于FileUtil确实读取了name引用的文件,因此您需要在文件系统中创建一个文件。
很容易做到这一点File tempFile = File.createTempFile("temp", ".tmp");
tempFile.deleteOnExit(true);
关于实施代码的一些话:
ArrayList<String> result = new ArrayList<String>();
// combine directory and file name like this
File f = new File(STORAGE_DIRECTORY, fileName);
// use try-with-resource here, like this:
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
result.add(sCurrentLine);
}
} catch (FileNotFoundException e) {
// no need to create a new list
return Collections.emptyList()
} catch (IOException e) {
return Collections.emptyList()
}
// you don't need to close the reader if you use try-with-resource
return result;
}
您当然可以使用Files#readAllLines。
try {
return Files.readAllLines(Paths.get(STORAGE_DIRECTORY, fileName), StandardCharsets.UTF-8);
} catch (IOException e) {
return Collections.emptyList();
}