模拟 java.nio.Files.class

问题描述

我正在尝试为班级编写单元测试:

public class ClasstoTest
{
    public WalkResult walk(URI path)
    {
        FileSystemWalkResult fileSystemWalkResult = new FileSystemWalkResult();

        Path share = Paths.get(path);
        try
        {
            Stream<Path> folders = Files.list(share).filter(Files::isDirectory);
            folders.forEach(Path -> {
                {
                    fileSystemWalkResult.getImmediateContainersInSortedOrder().add(Path.toUri());
                }
            });

        }
        catch (IOException | SecurityException e)
        {
           System.out.println("Exception in crawling folder:"+path.toString());
           e.printstacktrace();
        }
        return fileSystemWalkResult;
    }
}

这是我的单元测试:

@RunWith(powermockrunner.class)
@PrepareForTest({Files.class,ClasstoTest.class })
class ClasstoTestUTest
{

    @Mock
    private Path folder1;
    @Mock
    private Path folder2;
    
    private ClasstoTest underTest;
    @BeforeEach
    void setUp() throws Exception
    {
        powermockito.mockStatic(Files.class);
    }

    @Test
    void testWalk() throws IOException
    {
        String sharepath = "\\\\ip\\Share";
        Path temp = Paths.get(sharepath);
        
        Stream<Path> folders;
        ArrayList<Path> listofFolders = new ArrayList<Path>();
        listofFolders.add(folder1);
        listofFolders.add(folder2);
        folders = listofFolders.stream();
        
        when(Files.list(any())).thenReturn(folders);
        WalkResult actualWalkResult = underTest.walk(temp.toUri());
        
        //Check the walkresult object.
    }

}

当我运行这个时,模拟不起作用。我从实际的 Files.list() 方法中得到一个异常。 我也想模拟 (Paths.class) Paths.get() 调用,但暂时不要这样做。

Junit 错误

java.lang.NullPointerException 在 java.nio.file.Files.provider(Files.java:97) 在 java.nio.file.Files.newDirectoryStream(Files.java:457) 在 java.nio.file.Files.list(Files.java:3451) 在 com.filesystemconnector.ClasstoTestUTest.testWalk(ClasstoTestUTest.java:51)

我发现了许多与模拟这个 Files 类相关的问题。我使用的是 PowerMock 2.0.0 RC4 和 Mockito 2.23.4。

我哪里出错了?

解决方法

遇到了类似的问题。无法理解为什么 java.nio.file.Files 模拟失败和其他最终静态方法被模拟。

class ClassUnderTest {
    
    public void methodUnderTest() throws IOException {
        //bla bla
        Files.lines(null/*some path*/);
        //bla bla
        return;
    }
}

改成

class ClassUnderTest {
    
    public void methodUnderTest() throws IOException {
        //bla bla
        filesListWrapperMethod(null/*some path*/);
        //bla bla
        return;
    }
    
    @VisibleForTesting
    Stream<Path> filesListWrapperMethod(Path path) throws IOException {
        return Files.list(path);
    }

}

现在,您可以使用 Mockito.spy() 并模拟特定的 API。