我试图了解如何模拟静态方法,特别是静态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);
}
这有什么意义吗?有没有人不得不做类似的事情?任何帮助将不胜感激。
谢谢你的时间!
答案 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
)会更有意义。