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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20711964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 03:45:10  来源:igfitidea点击:

How to unit test a method that reads a given file

javafileunit-testingjunitmockito

提问by user2990315

I know this is a bit naive. How to unit test this piece of code without giving physical file as input. I am new to mockito and unit testing. So I am not sure. Please help.

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

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();
    }
}

采纳答案by Guillaume

You should probably refactor your method. As you realized, a method taking a file as input isn't easily testable. Also, it seems to be static, which doesn't help testability. If you rewrite your method as :

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

public String fileToString(BufferedReader input) throws IOException

it will be much easier to test. You separate your business logic form the technicalities of reading a file. As I understand it, your business logic is reading a stream and ensuring the line endings are unix style.

测试会容易得多。您将业务逻辑与读取文件的技术细节分开。据我了解,您的业务逻辑正在读取流并确保行尾是 unix 样式。

If you do that, your method will be testable. You also make it more generic : it can now read from a file, from a URL, or from any kind of stream. Better code, easier to test ...

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

回答by Amit Sharma

Why do you wanna mock a file? Mocking java.io.Fileis a bad idea as it has loads of native stuff. I would advice you to ensure that a minimalist text file is available in classpath when the unit tests are run. You can convert this file to text and confirm the output.

为什么要模拟文件?Mockingjava.io.File是一个坏主意,因为它包含大量原生内容。我建议您确保在运行单元测试时在类路径中提供一个极简的文本文件。您可以将此文件转换为文本并确认输出。

回答by Jeff Storey

You can create a file as part of the test, no need to mock it out.

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

JUnit does have a nice functionality for creating files used for testing and automatically cleaning them up using the TemporaryFolderrule.

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
    }
}

回答by MHPalang

you could use combination of ByteArrayInputStream and BufferedReader class, to make your required file within your code. So there wouldn't be any need to create a real File on your system. What would happen if you don't have enough permission --based of some specific circumstances -- to create a file. On the code below, you create your own desirable content of your file:

您可以使用 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){

        }
    }

}