Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 模拟目录流<;路径>;没有模仿迭代器是可能的吗?_Java_Unit Testing_Junit_Mocking_Powermock - Fatal编程技术网

Java 模拟目录流<;路径>;没有模仿迭代器是可能的吗?

Java 模拟目录流<;路径>;没有模仿迭代器是可能的吗?,java,unit-testing,junit,mocking,powermock,Java,Unit Testing,Junit,Mocking,Powermock,我有以下代码: Map<String, String> fileContentsByName = new HashMap<String, String>(); try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(directory)) { for (Path path : directoryStrea

我有以下代码:

        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)
        {
        }
Map fileContentsByName=newhashmap();
try(DirectoryStream DirectoryStream=Files.newDirectoryStream(directory))
{
for(路径:directoryStream)
{
if(Files.isRegularFile(path))
{
fileContentsByName.put(path.getFileName().toString(),新字符串(Files.readAllBytes(path));
}
}
}
捕获(IOE异常)
{
}
我正在尝试测试这个方法。我正在使用
Powermock
获取模拟的
DirectoryStream
。然而,当测试遇到代码中的每一个元素时,它会与一个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;
    }
}
公共类目录StreamReader{
公共映射读取(路径目录){
Map fileContentsByName=newhashmap();
try(DirectoryStream DirectoryStream=Files.newDirectoryStream(directory)){
for(路径:directoryStream){
if(Files.isRegularFile(path)){
fileContentsByName.put(path.getFileName().toString(),新字符串(Files.readAllBytes(path));
}
}
}捕获(IOE异常){
}
返回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()));
    }
}
@RunWith(PowerMockRunner.class)
@PrepareForTest({DirectoryStreamReader.class})
公共类DirectoryStreamTest{
@统治
public TemporaryFolder=new TemporaryFolder();
@试验
public void可以使用directoryStream()读取文件引发IOException{
mockStatic(Files.class);
Path directory=Mockito.mock(Path.class);
预期DirectoryStream=Mockito.mock(DirectoryStream.class);
Mockito.when(Files.newDirectoryStream(Mockito.any(Path.class)).thenReturn(预期);
File fileOne=folder.newFile();
File fileTwo=folder.newFile();
迭代器目录迭代器=Lists.newArrayList(path.get(fileOne.toURI()),
get(fileTwo.toURI()).iterator();
Mockito.when(应为.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 fileContentsByName=new DirectoryStreamReader().read(目录);
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({classthattcallthesystemclass.class})
      注释
    • 使用
      mockStatic(SystemClass.class)
      模拟系统类
  • 此测试通过JUnit4.12、Mockito 2.7.19和PowerMock 1.7.0进行验证

Dumb question-在
DirectoryStream
上对每个都使用与在
DirectoryStream
上调用
迭代器相同的方法?是的,for循环构造是迭代器上的语法糖。很好地展示了工作测试!不过,如果使用静态导入,它的阅读效果会更好。但更重要的是,我建议一个实际读取带有几个小文件的测试目录的测试会更好,代码更少,不耦合到SUT内部,并且不需要模拟库(在本例中是两个)。问题是如何模拟由
文件返回的
目录流
,因此我模拟了这些片段,但与
文件
实例的交互使用由
临时文件夹
规则创建的实际文件。重新考虑静态进口;由于测试是在没有import语句的情况下进行的,我认为明确静态导入可能有助于避免混淆。如果我是为自己编写这个代码+测试,我想我只会处理满足要求条件的实际文件,我也会使用静态导入:)@glytching你能回答这个任务吗,它与此类似