【问题标题】:Mockito - Mocking behaviour of a FileMockito - 文件的模拟行为
【发布时间】:2013-06-18 16:31:15
【问题描述】:

我有一个类,它接收一个文件,找到与之相关的文件,然后打开它。类似于

class DummyFileClass
{
    private File fileOne;
    private File fileTwo;
    public DummyFileClass(File fileOne)
    {
         this.fileOne = fileOne;
         fileTwo = findRelatedFile(fileOne)
    }

    public void someMethod()
    {
         // Do something with files one and two
    }

}

在我的单元测试中,我希望能够测试 someMethod() 而不必将物理文件放在某个地方。我可以模拟 fileOne,并将其传递给构造函数,但由于在构造函数中计算 fileTwo,我无法控制它。

我可以模拟 findRelatedFile() 方法 - 但这是最​​佳实践吗?在这里寻找最佳设计而不是实用的解决方法。我对模拟框架还很陌生。

【问题讨论】:

  • 这取决于someMethod() 应该做什么。它在这里返回 void。调用该方法对后续与你的对象交互有什么影响?
  • 它还没有实现,但计划是在每次调用时从文件中读取一点,直到它们都为空。
  • 嘲讽File 是,错误,好吧,很难。你为什么不想要一个测试文件?您可以对其进行结构化,使其足够轻松地适合您的测试用例......
  • 大多数情况下我只是想看看它是否/如何完成 :) 但是对于一个更通用的问题,如果 DummyFileClass 正在创建其他对象怎么办?尝试模拟内部创建的对象的行为(违反封装?)是不是很糟糕?
  • 这样的对象通常不定义你的类的接口;所以你不应该首先模拟它们;)至于模拟File,你可以将你的方法拆分为打开一个文件并打开一个InputStream到该文件。模拟输入流非常简单(只需让它返回一个 ByteArrayInputStream 并包含您选择的内容)

标签: java unit-testing mockito


【解决方案1】:

在这种情况下,我会使用物理文件来测试组件,而不是依赖模拟框架。正如fge 提到的那样,这可能更容易,而且您不必担心您可能对模拟做出的任何错误假设。

例如,如果您依赖 File#listFiles(),您的 mock 可能会返回一个固定的 Files 列表,但是,它们返回的顺序并不能保证 - 您可能只有在运行您的不同平台上的代码。

我会考虑使用 JUnit 的 TemporaryFolder 规则来帮助您设置测试所需的文件和目录结构,例如:

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

    @Test
    public void someMethod() {
        // given
        final File file1 = folder.newFile("myfile1.txt");
        final File file2 = folder.newFile("myfile2.txt");

        ... etc...
    }
}

该规则应在测试完成时清理所有创建的文件和目录。

【讨论】:

  • +1 PowerMock 可以模拟文件,但它通常比它的价值更麻烦。
  • 酷,不知道 TemporaryFolder,直到现在都在使用 .deleteOnExit :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-29
  • 2014-06-16
  • 1970-01-01
相关资源
最近更新 更多