繁体   English   中英

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

[英]Use Mockito to mock java.nio.file.Files static methods

我试图了解如何模拟静态方法,特别是来自静态 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;
}

}

这是一些显然不起作用的“伪类”单元测试代码,但我希望它描绘了我想要完成的工作的想法。

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

}

这有道理吗? 有没有人做过类似的事情? 任何帮助将不胜感激。

谢谢你的时间!

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

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

为了在无需准备和访问文件系统的情况下测试我的代码,我必须围绕这些函数编写一个自己的可模拟包装类。

虽然不是很好,但 nio JSR 没有通过定义官方接口并提供非静态(=可注入)方式来访问Files考虑这个用例。 Mockito 早在此之前就已为人所知..

除了使用 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的实例永远不会失败,并且您的测试不会检查您想要检查的内容.

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

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

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

你想通过newInputStream方法来测试什么? 您只是在创建一个同义反复——您的方法返回您告诉它返回的内容。 instanceof InputStream也是一个同义反复。

模拟JavaFileInput来测试另一个依赖它的类会更有意义(也许通过使用带有示例数据的ByteArrayInputStream )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM