我应该为java.nio.Files创建包装器以进行单元测试吗?

我正在尝试为下面的类编写单元测试,而不创建真正的文件

public class TempFileWritter{
    public String writeToTempFile(byte[] value) throws IOException {
        Path tempFile = Files.createTempFile(dir, prefix, suffix);
        Files.write(tempFile, value);
        return tempFile.toAbsolutePath().toString();
    }
}

我正在使用不能模拟静态方法的Mockito.所以我现在的解决方案是为java.nio.Files类编写一个包装类,我可以将它注入我的类,如下所示:

MyAppFileUtils类:

public class MyAppFileUtils {

    public void write(Path file, byte[] value) throws IOException {
        Files.write(file, value);
    }

    public Path createTempFile(Path dir, String prefix, String suffix) throws IOException {
        return Files.createTempFile(dir, prefix, suffix);
    }
}

修改后的类是:

public class TempFileWritter{
    MyAppFileUtils fileUtils;
    public void setFileUtils(MyAppFileUtils fileUtils) {
        this.fileUtils = fileUtils;
    }
    public String writeToTempFile(byte[] value) throws IOException {
        Path tempFile = fileUtils.createTempFile(dir, prefix, suffix);
        fileUtils.write(tempFile, value);
        return tempFile.toAbsolutePath().toString();
    }
}

有人认为创建类MyAppFileUtils是多余的,因为它除了在类java.nio.Files中调用方法之外什么都不做.你能给我一些建议吗?

最佳答案 使用
JimFs Java 7文件系统API的内存实现.

您需要确保您的代码允许替代文件系统实现,但它应该导致更多可扩展的代码,并且它更适合于模拟.

让我们说你的班级看起来像

public class TempFileWriter {

    private final Path tempDir;
    private final String prefix;
    private final String suffix;

    public TempFileWriter(Path tempDir, String prefix, String suffix) {
        this.tempDir = tempDir;
        this.prefix = prefix;
        this.suffix = suffix;
    }

    public Path writeToTempFile(byte[] value) throws IOException {
        Path tempFile = Files.createTempFile(tempDir, prefix, suffix);
        Files.write(tempFile, value);
        return tempFile;
    }
}

你的单元测试可能是

@Test
public void testCreateTempFile() throws IOException {
    FileSystem fs = Jimfs.newFileSystem();

    Path tempDir = fs.getPath("mytempdir");
    String prefix = "myprefix";
    String suffix = ".tmp";

    byte[] data = new byte[1];
    data[0] = 0x66;

    TempFileWriter tempFileWriter = new TempFileWriter(tempDir, prefix, suffix);
    tempFileWriter.writeToTempFile(data);

    Files.list(tempDir).forEach(path -> {
        String fileName = path.getName(0).toString();
        assertTrue(fileName.startsWith(prefix));
        assertTrue(fileName.endsWith(suffix));
        assertTrue(Files.readAllBytes(path)[0] == 0x66)
    });
}

您的代码现在更具扩展性,因为您可以使用不同的filesytem实现.
您的单元测试得到了改进,因为您不需要模拟任何东西.

点赞