不能模拟FileInputStream

时间:2019-08-09 13:16:32

标签: java spring junit mockito

我有

@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上的创建。

4 个答案:

答案 0 :(得分:2)

在下面的示例中,我转载了您的测试,对我有用。
(已通过JUnit 4Mockito 3.0.02.28.2验证)

我唯一更改的是Runner,但根据您的评论,您已经这样做了。

我删除了示例中的注释,因为在使用MockitoJUnitRunner执行测试时它们不相关,并更改了loadMappingsFromSource的返回类型以轻松添加该Assert.assertNotNull。 我还用CodesConverterException取代了RuntimeException

这些更改均不会影响测试本身。

mock的{​​{1}}已正确创建,即使仅存在带有参数的构造函数。

FileInputStream

答案 1 :(得分:0)

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();
        }

答案 2 :(得分:0)

我弄清楚了我同时使用@RunWith(SpringRunner.class)MockitoAnnotations.initMocks(this);的错误。如果同时使用这两种方法,则将创建怪人,但工作方式不正确。所以我刚刚删除了MockitoAnnotations.initMocks(this);

答案 3 :(得分:-1)

FileInputStream没有无参数构造函数。这就是Mockito无法实例化模拟的原因。

您可以尝试使其成为间谍并相应地模拟所需的方法:

@Spy
private FileInputStream fileInputStreamSpy = new FileInputStream("dummy");

修改

或者,您可以通过一种测试方法来创建模拟:

FileInputStream fileInputStreamMock = 
   Mockito.mock(FileInputStream.class, withSetting().useConstructor("dummy"));