Java 如何测试无效方法的文件实用程序?

Java how to test file utility that are void methods?

我将如何测试 类 或涉及写出文件或将文件从一个目录移动到另一个目录的方法?假设我将此辅助方法作为 Spring MVC 服务层方法之一:

private void writeFileOut(String fileContents, String fileName) throws IOException {
        File fullFilePath;
        FileWriter fileWriter = null;
        BufferedWriter bufferedWriter = null;
        try {
            fullFilePath = new File("/temp/directory/" + fileName);
            fileWriter = new FileWriter(fullFilePath);
            bufferedWriter = new BufferedWriter(fileWriter);
            if (bufferedWriter != null) {
                bufferedWriter.append(fileContents);
            }
        } catch (IOException e) {
            LOGGER.info("Error writing file out: " + e.getMessage());
            throw e;
        } finally {
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                throw e;
            }
        }
    }

这个方法到底有多可测试?它没有产生任何结果,我想不出一种方法来测试它是否正常工作。

测试写出文件:最好使用文件比较,即有参考文件(预期文件)并将其与生成的文件进行比较。

供您参考:Comparing text files with Junit

将文件从一个目录移动到另一个目录:移动文件后,您可以检查文件是否存在,例如。 file.exists() 在目标目录中,当然你也可以验证内容。

例如:File file = new File("目标文件夹中的文件路径"); assertTrue("文件不退出",file.exists());

首先要做的事情:为什么要重新发明轮子而不是使用 Files.writeString

假设您正在寻找一种更通用的解决方案来测试涉及文件系统的代码:我会尝试将任何外部资源(网络、数据库、其他进程、文件系统)排除在我的单元测试之外。您最终会得到依赖于例如文件系统详细信息的脆弱测试(延迟、测试之间的清理、并行测试 运行 可能会踩到彼此的脚趾)。

那么:请使用try with resources:

private void writeFileOut(String fileContents, String fileName) throws IOException {
    File fullFilePath = new File("/temp/directory/" + fileName);
    try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(fullFilePath))) {
        bufferedWriter.append(fileContents);
    }
    catch (IOException e) {
        LOGGER.info("Error writing file out: " + e.getMessage());
        throw e;
    }
}

现在你的代码做了 3 件事:

  • 创建文件路径
  • 将给定数据写入文件
  • 如果发生错误记录

将要测试的代码移到可以单独调用的新方法中通常最简单,而不必测试所有其他代码。因此隔离代码片段,尤其是尝试使用文件系统的代码。

private void writeFileOut(String fileContents, String fileName) throws IOException {
    File fullFilePath = new File(makeTempPath(fileName));
    try (Writer bufferedWriter = makeWriter(fullFilePath)) {
        bufferedWriter.append(fileContents);
    }
    catch (IOException e) {
        LOGGER.info("Error writing file out: " + e.getMessage());
        throw e;
    }
}

String makeTempPath(String fileName) {
    return "/temp/directory/" + fileName;
}

Writer makeWriter(String fullFilePath) {
    return new BufferedWriter(new FileWriter(fullFilePath));
}

现在您可以单独测试makeTempPath

您可以在测试 writeFileOut 时模拟 makeWriter。您可以检查它是否收到了它应该收到的内容。您可以让它抛出以触发错误处理。

模拟时,您可以使用 Mockito or you create a derived class for the methods you want to mock and override them. Note that makeWriter returns a Writer. In real life this is the BufferedWriter that writes to a file. In testing you can return a StringWriter 之类的框架来捕获写入的内容。

无论哪种方式,注意不要模拟太多,否则您最终可能只会测试您的模拟,而不是生产代码。