What I want to do is to mock newly created instance of BufferedReader
. Here's the code that should be tested:
A.java
...
@Override
public String read(String fileName) throws IOException {
...
try {
fileReader = new FileReader(fileName);
bufferedReader = new BufferedReader(fileReader);
String tmp;
StringBuilder builder = new StringBuilder();
while ((tmp = bufferedReader.readLine()) != null) {
builder.append(tmp);
}
return builder.toString();
} catch (IOException e) {
...
} finally {
...
}
}
...
What I have to do, is to PowerMock both FileReader
creation and BufferedReader
creation.
ATest.java
@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class ATest {
@Mock
private FileReader fileReader;
@Mock
private BufferedReader bufferedReader;
...
@Test
public void test() throws Exception {
PowerMockito.whenNew(FileReader.class).withArguments(FILE_NAME).thenReturn(fileReader);
PowerMockito.whenNew(BufferedReader.class).withAnyArguments().thenReturn(bufferedReader);
PowerMockito.doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) throws Throwable {
return "test";
}
}).when(bufferedReader).readLine();
assertArrayEquals(reader.read(FILE_NAME), new String[]{"test"});
}
}
But then the test never terminates. I can't even debug it.
As soon as PowerMockito.doAnswer()
is removed the code is executed (and is available for debugging). I've also tried to use Mockito.mock()
instead of PowerMockito.doAnswer()
, it doesn't help.
What may cause interminate execution of the test?
The problem was, that I also had to mock value after first bufferedReader.readLine()
, because otherwise it would always return the mocked value, thus not terminating.
Mockito.when(bufferedReader.readLine()).thenReturn("first line").thenReturn(null);
NOTE
Though this is the actual answer to the question, but you should strongly consider choosing the design GhostCat has suggested in another answer (which I eventually did).