Java 如何对读取给定文件的方法进行单元测试

Java 如何对读取给定文件的方法进行单元测试,java,file,unit-testing,junit,mockito,Java,File,Unit Testing,Junit,Mockito,我知道这有点天真。如何在不提供物理文件作为输入的情况下对这段代码进行单元测试。 我不熟悉mockito和单元测试。所以我不确定。请帮忙 public static String fileToString(File file) throws IOException { BufferedReader br = new BufferedReader(new FileReader(file)); try { StringBuilder sb = new StringBui

我知道这有点天真。如何在不提供物理文件作为输入的情况下对这段代码进行单元测试。 我不熟悉mockito和单元测试。所以我不确定。请帮忙

public static String fileToString(File file) throws IOException
{
    BufferedReader br = new BufferedReader(new FileReader(file));
    try {
        StringBuilder sb = new StringBuilder();
        String line = br.readLine();

        while (line != null) {
            sb.append(line);
            sb.append("\n");
            line = br.readLine();
        }
        return sb.toString();
    } finally {
        br.close();
    }
}

你为什么要模仿一个文件?模仿
java.io.File
是个坏主意,因为它有大量的本地内容。我建议您确保在运行单元测试时,类路径中有一个最简单的文本文件。您可以将此文件转换为文本并确认输出。

您可以创建一个文件作为测试的一部分,无需模拟它

JUnit确实有一个很好的功能,可以创建用于测试的文件,并使用
TemporaryFolder
规则自动清理这些文件

public class MyTestClass {

    @Rule
    public TemporaryFolder folder = new TemporaryFolder();

    @Test
    public void myTest() {
        // this folder gets cleaned up automatically by JUnit
        File file = folder.newFile("someTestFile.txt");

        // populate the file
        // run your test
    }
}

您可能应该重构您的方法。正如您所意识到的,以文件作为输入的方法不容易测试。而且,它似乎是静态的,这无助于可测试性。如果将方法重写为:

public String fileToString(BufferedReader input) throws IOException
这将更容易测试。您将业务逻辑与读取文件的技术细节分开。据我所知,您的业务逻辑是读取流,并确保行结尾是unix风格的


如果您这样做,您的方法将是可测试的。您还使它更通用:它现在可以从文件、URL或任何类型的流中读取。更好的代码,更容易测试…

您可以使用ByteArrayInputStream和BufferedReader类的组合,在代码中生成所需的文件。因此,不需要在系统上创建真正的文件。如果您没有足够的权限(基于某些特定情况)创建文件,会发生什么。在下面的代码中,您可以创建自己想要的文件内容:

public static void main(String a[]){

    String str = "converting to input stream"+
                    "\n and this is second line";
    byte[] content = str.getBytes();
    InputStream is = null;
    BufferedReader bfReader = null;
    try {
        is = new ByteArrayInputStream(content);
        bfReader = new BufferedReader(new InputStreamReader(is));
        String temp = null;
        while((temp = bfReader.readLine()) != null){
            System.out.println(temp);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try{
            if(is != null) is.close();
        } catch (Exception ex){

        }
    }

}

看看链接的示例中接受的答案,我认为他正在使用一个物理文件来测试代码。我想在不带文件的情况下测试一下,谢谢。但不读取物理文件不是违反单元测试的最佳实践吗?不。我不这么认为。单元测试的全部要点是在“功能单元”中编写代码,然后用一个小样本输入测试每个单元,并验证您是否获得了这个小样本输入的正确输出。但这不符合不读取物理文件的单元测试最佳实践吗?不,我不会这么说。我不认为使用真实对象是有问题的,尤其是当它使测试变得非常容易时。对于一个像对象一样的文件,它几乎在每个Java应用程序中都经过了严格的测试和使用(因此它可能工作得很好),并且有各种与操作系统相关的东西,使用一个真实的文件没有什么害处。该方法只使用一次,也只在类中使用一次。它是否使它成为一个很好的候选,使它成为一个很好的候选,使它成为私有的,而不是测试它,而不是使它成为静态的。您的测试应该与实现无关,但测试被测单元的行为(大多数情况下是类)。我不明白你的建议。使用bufferedreader我可以模拟bufferedreader输入吗?或者我可以轻松地向缓冲读取器添加内容,这样我就可以测试它而不是文件输入。要实现100%的代码覆盖率,还需要测试私有方法。使用StringReader的帮助,不依赖于文件。