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.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).