9

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

4

4 回答 4

19

我发现MockitoPowermock是一个很好的组合。实际上有一个带有示例的博客文章,其中 File-class 的构造函数被模拟用于测试目的。这也是我放在一起的一个小例子:

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

使用 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();
    }
}
于 2012-08-07T16:30:09.717 回答
2

如果您使用 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");
      // ...
     }
 }

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

    [...]
    pw = new PrintWriter(folder.getAbsolutePath() + '/' + filename);
    pw.println(data);
于 2018-01-08T21:12:34.753 回答
0

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

于 2012-08-07T16:18:30.303 回答
-2

这是非常不赞成的:

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

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

来源

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

于 2012-08-07T16:05:52.970 回答