首页 > 解决方案 > 我可以模拟方法内部的 file.mkdirs()

问题描述

下面是我的遗留代码。我不想创建一个实际的文件夹。相反,我想创建一个临时文件夹,在测试执行结束后必须将其删除。

Public class MainClass() {
  public void m1() {
        m2();
  }

  private void m2() {
    File f=new File();
    f.mkrdirs()
  }
}

这是我的TestClass

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

       public void testM1(){
            File fileSpy = mock(File.class);
            Mockito.doNothing().when(fileSpy.mkdir());

       }
}

但不工作。任何线索?

标签: javafilejunitmocking

解决方案


您的问题从这里开始:

File f=new File();

您的生产代码为文件类调用new。在您的测试代码中,您执行以下操作:

File fileSpy = mock(File.class);

那个间谍与你的f实例有什么关系?答:完全没有。

在你的测试中声明一个间谍不会神奇地让你的生产代码使用它!因此,您必须确保当您的生产代码使用该f对象时......f应该是您的fileSpy

现在您有以下选择:

  • 看看您是否可以更改您的生产代码,以便您可以以某种方式传递文件实例。通过使其成为一个参数,您真的可以将某些东西传递给,或者通过变成f您的类的一个字段,然后使用 Mockito 的 @InjectMock 注释
  • 如果您坚持使用生产代码,Mockito 不会这样做。然后你需要 PowerMock(ito) 或 JMockit。

通常,我建议人们坚持使用普通的 Mockito,并避免像瘟疫一样通过 PowerMock(ito)模拟 new() (更是如此模拟静态调用)。

但是测试遗留代码是您必须在“根本不测试”或“使用 PowerMock(ito) 测试”之间进行选择的一种情况。因此,如果您无法更改生产代码,那么您唯一的选择就是模拟对 new() 的调用。请参阅此处了解如何执行此操作。


推荐阅读