[英]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.