使用Mockito来模拟java.nio.file.Files静态方法

时间:2014-06-19 02:58:37

标签: java unit-testing mockito

我试图了解如何模拟静态方法,特别是静态Files.class。

基本上,只要这一行执行:

 Files.newInputStream(this.getPathObj(), StandardOpenOption.READ);

我希望它只返回一个作为InputStream实例的对象。

这是我的类,我正在尝试模拟静态方法。

public class JavaFileInput{

private Path path;

public JavaFileInput(Path path){
    this.path = path;
}

public InputStream getInputStream() throws IOException {
    return Files.newInputStream(this.getPathObj(), StandardOpenOption.READ);
}

public Path getPathObj() {
    return this.path;
}

}

这是一些“psuedo-ish”单元测试代码显然不起作用,但我希望它描绘了我想要实现的目标。

@Mock(name="path")
private Path mockedPath = Mockito.mock(Path.class);

@InjectMocks
private JavaFileInput javaFile_MockedPath;

@Before
public void testSetup(){
  javaFile_MockedPath = new JavaFileInput(mockedPath);
  MockitoAnnotations.initMocks(this);
}

@Test
public void getNewInputStreamTest(){
    //Setup
    Mockito.when(Files.newInputStream(mockedPathObj, StandardOpenOption.Read)).thenReturn(new InputStream());

    //Test
    InputStream outputValue = javaFile_MockedPath.getInputStream();

    //Validate
    assertTrue(outputValue instanceof InputStream);

}

这有什么意义吗?有没有人不得不做类似的事情?任何帮助将不胜感激。

谢谢你的时间!

4 个答案:

答案 0 :(得分:1)

我不清楚JavaFileInput提供的价值。但是,要测试静态方法,您可以查看PowerMock

答案 1 :(得分:0)

我遇到了同样的问题:我有(自己的)代码,可使用nio.Files修改符号链接。

为了测试我的代码而不必准备和访问文件系统,我不得不围绕这些函数编写自己的可模拟包装器类。

不太好,尽管nio JSR并未通过定义官方接口并提供用于访问Files的非静态(=可注入)方式来考虑此用例。 Mockito在此之前就广为人知。

答案 2 :(得分:0)

除了使用Mockito或PowerMock,您还可以使用在内存中运行的NIO2实现:

尽管这不能解决所有情况(或者说,它不能回答您模拟静态方法的尝试),或者可以让您创建有缺陷的InputStream(例如,将返回一个错误的{读取N个字节时出错),这可能适合您的用例。

还请问您的案件是否有意义:

//Setup
Mockito.when(Files.newInputStream(mockedPathObj, StandardOpenOption.Read)).thenReturn(new InputStream());

//Test
InputStream outputValue = javaFile_MockedPath.getInputStream();

//Validate
assertTrue(outputValue instanceof InputStream);

您正在测试outputValue确实是InputStream的实例,编译器已经为您执行了此操作:outputValue已经是InputStream的实例,因此对其进行断言是InputStream的实例将永远不会失败,并且您的测试不会检查您要检查的内容。

您最好使用模拟而不是outputValue来测试new InputStream与返回的实例完全相同,例如:

InputStream is = mock(InputStream.class);
Mockito.when(Files.newInputStream(mockedPathObj, StandardOpenOption.Read)).thenReturn(is);
InputStream outputValue = javaFile_MockedPath.getInputStream();
assertTrue(outputValue == is);

答案 3 :(得分:-1)

使用标准Mockito,您无法模拟静态方法 - 我会质疑您这样做的原因。

你试图通过嘲笑newInputStream方法来测试什么?你只是在创建一个重言式 - 你的方法会返回你告诉它返回的内容。 instanceof InputStream也是同义反复。

模拟JavaFileInput以测试依赖于它的另一个类(可能使用带有样本数据的ByteArrayInputStream)会更有意义。