java 用Java模拟文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11849728/
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-10-31 06:38:19  来源:igfitidea点击:

Simulate File in Java

javaunit-testing

提问by Frank

I'm trying to write unit tests for a method that takes a String filename, then opens the file and reads from it. So, to test that method, I thought about writing a file, then calling my method. However, in the build farm, it is not possible to write files arbitrarily to disk. Is there a standard way to "simulate" having a real file in my unit test?

我正在尝试为采用字符串文件名的方法编写单元测试,然后打开文件并从中读取。因此,为了测试该方法,我考虑编写一个文件,然后调用我的方法。但是,在构建场中,不可能将文件任意写入磁盘。有没有标准的方法来“模拟”在我的单元测试中有一个真实的文件?

采纳答案by Woot4Moo

This is highly frowned upon:

这是非常不赞成的:

The smallest amount of testable code. Often a single method/function, sans the use of other methods or classes. Fast! Thousands of unit tests can run in ten seconds or less! A unit test NEVER uses:

  • a database
  • an app server (or server of any kind)
  • file/network I/O or file system;
  • another application;
  • the console (System.out, System.err, etc.)
  • logging
  • most other classes (exceptions include DTO's, String, Integer, mocks and maybe a few others). "

最少量的可测试代码。通常是单个方法/函数,不使用其他方法或类。快速地!数以千计的单元测试可以在十秒或更短的时间内运行!单元测试从不使用:

  • 数据库
  • 应用服务器(或任何类型的服务器)
  • 文件/网络 I/O 或文件系统;
  • 另一个应用程序;
  • 控制台(System.out、System.err 等)
  • 日志记录
  • 大多数其他类(例外包括 DTO、String、Integer、mocks 和其他一些类)。”

Source

来源

If you must read from a file, have a test file pre-generated that all unit tests read from. There is no need to write anything to disk.

如果您必须从文件中读取,请预先生成一个所有单元测试都从中读取的测试文件。无需向磁盘写入任何内容。

回答by esaj

I've found that Mockitoand Powermockare a good combination for this. Actually there's a blog postwith a sample, where the File-class's constructor is mocked for testing purposes. Here's also a small example I threw together:

我发现MockitoPowermock是一个很好的组合。实际上有一篇带有示例的博客文章,其中出于测试目的模拟了 File 类的构造函数。这也是我拼凑的一个小例子:

public class ClassToTest
{
    public void openFile(String fileName)
    {
        File f = new File(fileName);
        if(!f.exists())
        {
            throw new RuntimeException("File not found!");
        }
    }
}

Testing with Mockito + Powermock:

使用 Mockito + Powermock 进行测试:

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassToTest.class)
public class FileTest
{
    @Test
    public void testFile() throws Exception
    {
        //Set up a mocked File-object
        File mockedFile = Mockito.mock(File.class);
        Mockito.when(mockedFile.exists()).thenReturn(true);

        //Trap constructor calls to return the mocked File-object
        PowerMockito.whenNew(File.class).withParameterTypes(String.class).withArguments(Matchers.anyString()).thenReturn(mockedFile);

        //Do the test
        ClassToTest classToTest = new ClassToTest();
        classToTest.openFile("testfile.txt");

        //Verify that the File was created and the exists-method of the mock was called
        PowerMockito.verifyNew(File.class).withArguments("testfile.txt");
        Mockito.verify(mockedFile).exists();
    }
}

回答by comodoro

If you use JUnit, there is the TemporaryFolder. Files are deleted after the test. Example given on the page:

如果您使用 JUnit,则有TemporaryFolder。测试后删除文件。页面上给出的示例:

public static class HasTempFolder {
  @Rule
  public TemporaryFolder folder= new TemporaryFolder();

  @Test
  public void testUsingTempFolder() throws IOException {
      File createdFile= folder.newFile("myfile.txt");
      File createdFolder= folder.newFolder("subfolder");
      // ...
     }
 }

However, I have also used it for testing my Android class read/write capabilities like:

但是,我也用它来测试我的 Android 类读/写功能,例如:

    [...]
    pw = new PrintWriter(folder.getAbsolutePath() + '/' + filename);
    pw.println(data);

回答by Vic

How about using mocked stream classes, which override the real ones (like BufferredReader, File) completely (meaning all methods or all methods you use)? The data can be saved as an array of bytes, for example, in some singleton, if they are to be used between different test classes.

如何使用模拟流类,它完全覆盖真实的流类(如 BufferredReader、File)(意味着所有方法或您使用的所有方法)?数据可以保存为字节数组,例如,在某些单例中,如果它们要在不同的测试类之间使用。