我可以模拟方法内部的file.mkdirs()吗

时间:2019-05-09 06:20:52

标签: java file junit mocking

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

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

       }
}

但不起作用。有任何线索吗?

1 个答案:

答案 0 :(得分:5)

您的问题从这里开始:

File f=new File();

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

File fileSpy = mock(File.class);

那间谍与您的f实例有什么关系?答:一点也不。

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

现在您有以下选择:

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

通常,我建议人们坚持使用普通的Mockito,避免像瘟疫一样通过PowerMock(ito)嘲笑new()(甚至嘲笑 static 调用)。

但是测试遗留代码是一种情况,您必须在“完全不测试”或“使用PowerMock(ito)测试”之间进行选择。因此,如果您无法更改生产代码,那么唯一的选择就是模拟对new()的调用。有关具体操作,请参见here