Issue
how can I unit test a method which uses try-with-resources?
As it uses new operator in try clause I cannot mock it. I don't want to use PowerMock. It seems like the only way is to create integration test?
public void methodToBeTested(File file) {
try (FileInputStream fis = new FileInputStream(file)) {
//some logic I want to test which uses fis object
} catch (Exception e) {
//print stacktrace
}
}
Solution
You could move the dependency instantiation into a factory class and pass that as constructor parameter to your code under test. The factory class itself would be too simple to fail and therfore not needed to be tested.
do you propose to do something like:
try (FileInputStream fis = getCreatedFromFactory(file)) ??
– JavaIntern
Almost...
@Singleton
public class InputStreamFactory { // too simple to fail -> no UnitTests
public InputStream createFor(File file) throws IOException, FileNotFoundException {
retrun new FileInputStream(file);
}
}
class UnitUnderTest {
private final InputStreamFactory inputStreamFactory;
UnitUnderTest(@Inject InputStreamFactory inputStreamFactory){
this.inputStreamFactory=inputStreamFactory;
}
public void methodToBeTested(File file) {
try (FileInputStream fis = inputStreamFactory.createFor(file)) {
//some logic I want to test which uses fis object
} catch (Exception e) {
//print stacktrace
}
}
}
class UnitUnderTestTest{
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Mock
private InputStreamFactory inputStreamFactory;
@Mock
private InputStream inputStream;
private final File inputFile = new File("whatever");
// no init here, mock for inputStream not yet created
private UnitUnderTest unitUnderTest;
/* I don't use @InjectMocks
since it does not cause compile error
if constructor misses parameter */
@Before
public void setup() {
unitUnderTest = new UnitUnderTest(inputStreamFactory);
doReturn(inputStream).when(inputStreamFactory).createFor(any(File.class);
}
@Test
public void createsInputStreamFromFilePassed() {
// arrange
/* nothing to do */
// act
new UnitUnderTest(inputStreamFactory).methodToBeTested(inputFile);
// assert
verify(inputStreamFactory).createFor(inputFile);
verify(inputStream).close();
}
}
Answered By - Timothy Truckle
Answer Checked By - Candace Johnson (JavaFixing Volunteer)