gpt4 book ai didi

java - 可以在不模拟迭代器的情况下模拟 DirectoryStream 吗?

转载 作者:行者123 更新时间:2023-11-30 02:20:10 27 4
gpt4 key购买 nike

我有以下代码:

        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被 mock DirectoryStream<Path> 。然而,当测试在代码中遇到 for-each 时,它会因 NPE 而崩溃。如何指定 DirectoryStream 中的路径?

我考虑过更改源代码以使用迭代器并模拟 DirectoryStream 的迭代器以提供所需的路径,但我想知道是否有更好的替代方案?

最佳答案

假设您上面提供的代码片段是在如下类中定义的:

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()));
}
}

这里的要点是:

  • 使用 JUnit 的 TemporaryFolder 规则创建和丢弃一些供测试使用的文件
  • 使用 PowerMockito 模拟与 java.nio.file.Files 的所有交互,这是一个最终类,被模拟的方法是静态的,因此需要 PowerMockito
  • mocking a system class 时遵循 PowerMockito 建议, 具体来说:
    • 在测试用例的类级别使用 @RunWith(PowerMockRunner.class) 注释。
    • 在测试用例的类级别使用 @PrepareForTest({ClassThatCallsTheSystemClass.class}) 注解。
    • 使用mockStatic(SystemClass.class)来模拟系统类
  • 此测试已使用 Junit 4.12、Mockito 2.7.19 和 PowerMock 1.7.0 进行验证

关于java - 可以在不模拟迭代器的情况下模拟 DirectoryStream<Path> 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47101232/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com