首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以在没有模拟迭代器的情况下模拟DirectoryStream<Path>?

是否可以在没有模拟迭代器的情况下模拟DirectoryStream<Path>?
EN

Stack Overflow用户
提问于 2017-11-03 17:20:17
回答 1查看 1.6K关注 0票数 2

我有以下代码:

代码语言:javascript
复制
        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的迭代器以提供所需的路径,但我想知道是否有更好的选择?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-03 21:26:41

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

代码语言:javascript
复制
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;
    }
}

然后,以下测试将通过:

代码语言:javascript
复制
@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
  • 遵循PowerMockito建议时模拟系统类,特别是:
    • 在测试用例的类级别使用@RunWith(PowerMockRunner.class)注释。
    • 在测试用例的类级别使用@PrepareForTest({ClassThatCallsTheSystemClass.class})注释。
    • 使用mockStatic(SystemClass.class)模拟系统类

  • 该测试用Junit 4.12、Mockito 2.7.19和PowerMock 1.7.0进行了验证。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47101232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档