测试中FileInputStream实例始终为null?已用工厂类规避PowerMock
f Variable Is Null in the Test Let's break down why you're seeing f as null and how to fix it:
Root Causes
1. Missing Mock Initialization
You're using @RunWith(SpringRunner.class), but this runner doesn't automatically handle Mockito's @Mock and @InjectMocks annotations. Without initializing Mockito, your mocked objects stay null, so when CodesConverterService tries to use fileInputStreamFactory, it's actually operating on a null reference.
2. Unresolved Constructor Dependency
Look at your CodesConverterService constructor:
public CodesConverterService(FileInputStreamFactory fileInputStreamFactory, YamlFactory yamlFactory) { this.fileInputStreamFactory = fileInputStreamFactory; }
It requires two parameters, but your test only mocks FileInputStreamFactory. Mockito's @InjectMocks can't instantiate CodesConverterService without a mock for YamlFactory, so the service itself might not be properly initialized either.
Fixes
Option 1: Initialize Mockito in JUnit 4
Add a setup method to initialize Mockito's annotations, and mock the missing YamlFactory:
@RunWith(SpringRunner.class) public class CodesConverterServiceTest { @InjectMocks private CodesConverterService codesConverterService; @Mock private FileInputStreamFactory fileInputStreamFactory; @Mock private YamlFactory yamlFactory; // Add this missing mock @Mock private FileInputStream fileInputStream; @Before public void setUp() { MockitoAnnotations.openMocks(this); // Initialize Mockito annotations } @Test public void whenLoadMappingsFromSource_GoodPath() throws FileNotFoundException { // Stub the mock behavior when(fileInputStreamFactory.getStream("mappingFile")).thenReturn(fileInputStream); // Execute the method this.codesConverterService.loadMappingsFromSource(); // Verify the mock was called (optional but good practice) verify(fileInputStreamFactory).getStream("mappingFile"); } }
Option 2: Use Mockito's Runner Directly
Replace SpringRunner with MockitoJUnitRunner (this handles annotation initialization automatically):
@RunWith(MockitoJUnitRunner.class) // Switch to Mockito's runner public class CodesConverterServiceTest { @InjectMocks private CodesConverterService codesConverterService; @Mock private FileInputStreamFactory fileInputStreamFactory; @Mock private YamlFactory yamlFactory; // Add this missing mock @Mock private FileInputStream fileInputStream; @Test public void whenLoadMappingsFromSource_GoodPath() throws FileNotFoundException { when(fileInputStreamFactory.getStream("mappingFile")).thenReturn(fileInputStream); this.codesConverterService.loadMappingsFromSource(); // Verify interaction verify(fileInputStreamFactory).getStream("mappingFile"); } }
Why This Works
- Adding
YamlFactoryas a mock satisfies the constructor dependency, letting@InjectMocksproperly createCodesConverterService. - Initializing Mockito ensures your mocked objects are created and injected into the service, so when
fileInputStreamFactory.getStream()is called, it uses your stubbed return value instead of trying to create a realFileInputStream.
内容的提问来源于stack exchange,提问作者Anton Kolosok

