我有以下代码:
Map<String, String> fileContentsByName = new HashMap<String, String>();
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(directory))
{
for (Path path : directoryStream)
{
if (Files.isRegularFile(path))
{
fileContentsByName.put(path.getFileName().toString(), new String(Files.readAllBytes(path)));
}
}
}
catch (IOException e)
{
}
我正在尝试测试此方法。我使用Powermock
来获取被模拟的DirectoryStream<Path>
。但是,当测试遇到代码中的每一个时,它会随着NPE而爆炸。如何在DirectoryStream中指定路径?
我已经考虑过更改源代码以使用迭代器和模拟DirectoryStream的迭代器来提供所需的路径,但我想知道是否有更好的替代方案?
答案 0 :(得分:2)
假设您在上面提供的代码段是在如下的类中定义的:
public class DirectoryStreamReader {
public Map<String, String> read(Path directory) {
Map<String, String> fileContentsByName = new HashMap<String, String>();
try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(directory)) {
for (Path path : directoryStream) {
if (Files.isRegularFile(path)) {
fileContentsByName.put(path.getFileName().toString(), new String(Files.readAllBytes(path)));
}
}
} catch (IOException e) {
}
return fileContentsByName;
}
}
然后将通过以下测试:
@RunWith(PowerMockRunner.class)
@PrepareForTest({DirectoryStreamReader.class})
public class DirectoryStreamTest {
@Rule
public TemporaryFolder folder= new TemporaryFolder();
@Test
public void canReadFilesUsingDirectoryStream() throws IOException {
PowerMockito.mockStatic(Files.class);
Path directory = Mockito.mock(Path.class);
DirectoryStream<Path> expected = Mockito.mock(DirectoryStream.class);
Mockito.when(Files.newDirectoryStream(Mockito.any(Path.class))).thenReturn(expected);
File fileOne = folder.newFile();
File fileTwo = folder.newFile();
Iterator<Path> directoryIterator = Lists.newArrayList(Paths.get(fileOne.toURI()),
Paths.get(fileTwo.toURI())).iterator();
Mockito.when(expected.iterator()).thenReturn(directoryIterator);
Mockito.when(Files.isRegularFile(Mockito.any(Path.class))).thenReturn(true);
Mockito.when(Files.readAllBytes(Mockito.any(Path.class))).thenReturn("fileOneContents".getBytes()).thenReturn("fileTwoContents".getBytes());
Map<String, String> fileContentsByName = new DirectoryStreamReader().read(directory);
Assert.assertEquals(2, fileContentsByName.size());
Assert.assertTrue(fileContentsByName.containsKey(fileOne.getName()));
Assert.assertEquals("fileOneContents", fileContentsByName.get(fileOne.getName()));
Assert.assertTrue(fileContentsByName.containsKey(fileTwo.getName()));
Assert.assertEquals("fileTwoContents", fileContentsByName.get(fileTwo.getName()));
}
}
这里的关键点是:
TemporaryFolder
规则来创建和丢弃一些供测试使用的文件java.nio.file.Files
的所有交互,这是一个最终类,被模拟的方法是静态的,因此需要PowerMockito @RunWith(PowerMockRunner.class)
注释。@PrepareForTest({ClassThatCallsTheSystemClass.class})
注释。mockStatic(SystemClass.class)
模拟系统类