[英]Can`t mock FileInputStream
我有
@Component
public class CodesConverterService {
private final FileInputStreamFactory fileInputStreamFactory;
public CodesConverterService(FileInputStreamFactory fileInputStreamFactory, YamlFactory yamlFactory) {
this.fileInputStreamFactory = fileInputStreamFactory;
}
@EventListener(ApplicationReadyEvent.class)
public void loadMappingsFromSource() {
try {
FileInputStream f = fileInputStreamFactory.getStream("mappingFile");
} catch (Exception e) {
throw new CodesConverterException("Can`t load mappings from source");
}
}
我的FileInputStreamFactory:
@Component
public class FileInputStreamFactory {
public FileInputStream getStream(final String file) throws FileNotFoundException {
return new FileInputStream(file);
}
}
我的测试
@RunWith(SpringRunner.class)
public class CodesConverterServiceTest {
@InjectMocks
private CodesConverterService codesConverterService;
@Mock
private FileInputStreamFactory fileInputStreamFactory;
@Mock
private FileInputStream fileInputStream;
@Test
public void whenLoadMappingsFromSource_GoodPath() throws FileNotFoundException {
when(fileInputStreamFactory.getStream("mappingFile")).thenReturn(fileInputStream);
this.codesConverterService.loadMappingsFromSource();
}
为什么我的f总是为null? 我试过分配变化。 但它始终为空。 我已经为FileInputStream创建了工厂,因为我不想在测试中使用PowerMock模拟新FileInputStream上的创建。
我在下面的示例中重现了您的测试,该测试对我有用。
(已通过JUnit 4
和Mockito
3.0.0
和2.28.2
)
我唯一更改的是Runner
,但根据您的评论,您已经这样做了。
我删除该示例中的注释作为当测试与执行他们应该是不相关的MockitoJUnitRunner
和改变的返回类型loadMappingsFromSource
容易地添加Assert.assertNotNull
。 我还用RuntimeException
替换了CodesConverterException
。
这些更改均不会影响测试本身。
即使仅存在带有参数的构造函数,也可以正确创建FileInputStream
的mock
。
@RunWith(MockitoJUnitRunner.class)
public class CodesConverterServiceTest {
class YamlFactory {
}
class FileInputStreamFactory {
public FileInputStream getStream(final String file) throws FileNotFoundException {
return new FileInputStream(file);
}
}
static class CodesConverterService {
private final FileInputStreamFactory fileInputStreamFactory;
public CodesConverterService(FileInputStreamFactory fileInputStreamFactory, YamlFactory yamlFactory) {
this.fileInputStreamFactory = fileInputStreamFactory;
}
public FileInputStream loadMappingsFromSource() {
try {
return fileInputStreamFactory.getStream("mappingFile");
} catch (Exception e) {
throw new RuntimeException("Can`t load mappings from source");
}
}
}
@InjectMocks
private CodesConverterService codesConverterService;
@Mock
private FileInputStreamFactory fileInputStreamFactory;
@Mock
private FileInputStream fileInputStream;
@Test
public void whenLoadMappingsFromSource_GoodPath() throws FileNotFoundException {
Mockito.when(fileInputStreamFactory.getStream("mappingFile")).thenReturn(fileInputStream);
Assert.assertNotNull(codesConverterService.loadMappingsFromSource());
}
}
1)尝试以下代码:
@Test
public void itShouldReturnFileInputStream() {
FileInputStreamFactory mockFileInputStreamFactory = mock(FileInputStreamFactory.class);
FileInputStream mockFileInputStream = mock(FileInputStream.class);
Mockito.doReturn(mockFileInputStream).when(mockFileInputStreamFactory).getStream("fileName");
CodesConverterService codeConverterService = new CodesConverterService(mockFileInputStreamFactory);
assertThatCode(() -> codeConverterService.codeConverterService()).doesNotThrowAnyException();
}
我弄清楚我在使用@RunWith(SpringRunner.class)
和MockitoAnnotations.initMocks(this);
是什么错误MockitoAnnotations.initMocks(this);
同时。 如果同时使用这两种方法,则将创建怪人,但工作方式不正确。 所以我只是删除了MockitoAnnotations.initMocks(this);
FileInputStream没有no-arg构造函数。 这就是Mockito无法实例化模拟的原因。
您可以尝试使其成为间谍,并相应地模拟所需的方法:
@Spy
private FileInputStream fileInputStreamSpy = new FileInputStream("dummy");
编辑 :
另外,您可以通过以下方式在测试方法中创建模拟:
FileInputStream fileInputStreamMock =
Mockito.mock(FileInputStream.class, withSetting().useConstructor("dummy"));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.