模拟辅助方法的 return-value

Mocking the return-value of a helper method

我正在尝试使用 Mockito 测试这段代码

if (writeToDisk(filename, byteArray)){
    return "URI1"
} else {
    return "URI2"
}

由于 writeToDisk 旨在 运行 在 unix 服务器上,因此使用缓冲+fileWriter 写入“/tmp/upload”。 问题是我正在 windows 机器上编写单元测试,而 writeToDisk 总是 returns 错误,因为 java 在 windows 上找不到“/tmp/upload”。

有什么方法可以模拟 writeToDisk 的结果,一个 pacakge 私有方法?

这就是 writeToDisk 的作用:

boolean writeToDisk(String filename, byte[] data){
    boolean writeSuccessful = false;
    try (BufferedWriter writer = new BufferedWriter(new FileWriter("/tmp/upload"+ filename"))){
        for (byte current : data){
            out.write(current);
        }
        writeSuccessful =true;
    } catch (IOException e) {
        LOG.debug(e);
    }
    return writeSuccessful;
}

真正的答案在这里:

try (BufferedWriter writer = new BufferedWriter(new FileWriter("/tmp/upload"+ filename"))){

您在这里硬编码了很多东西,例如那个(OS 特定的)路径,以及确切的作者类型。这使得这个客户(只想在某个地方写东西)非常依赖所有这些方面。因此它变得非常难以测试!

您可以轻松地将所有这些方面转变为某种服务,您只需前往:

try (Writer writer = service.getWriterFor(filename))

(或类似的东西,只是在这里提供一些灵感)

您可以轻松模拟该服务,直接使您也可以将该代码组合起来。

这只是一个非常小的抽象(可能是一些@FunctionalInterface,可以在生产中用一个很好的 lambda 或方法引用来初始化)。

单元测试的优点之一是它迫使您改进设计。

所以是的,正如其他人所建议的,您需要添加依赖注入。

我建议你创建一个名为 FileCreator 的 class 并给它一个方法 boolean createFile(byte[]) 如果你需要的话也许可以 String getCreatedFileName().

作为一个额外的优势,文件名似乎不需要成为调用的一部分,并且可以转换为新 class 的 属性。

另一个潜在的优势:如果你的代码变成多线程的,你可以有一个创建者每个线程,所有写入不同的文件。