Reputation: 55
I have to throw an IOException
using Mockito for a method, which is reading an input stream like given below. Is there any way to do it?
public void someMethod() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
firstLine = in.readLine();
} catch(IOException ioException) {
// Do something
}
...
}
I tried mocking like
BufferedReader buffReader = Mockito.mock(BufferedReader.class);
Mockito.doThrow(new IOException()).when(buffReader).readLine();
but didn't work out :(
Upvotes: 5
Views: 22294
Reputation: 79875
The way that I would recommend is to have an extra class that looks after the creation of the BufferedReader
. This class has just one method, with no actual logic in it, so it doesn't need any unit tests.
public class BufferedReaderFactory{
public BufferedReader makeBufferedReader(InputStream input) throws IOException{
return new BufferedReader(new InputStreamReader(input));
}
}
Now, add a private field of type BufferedReaderFactory
to the class that you're testing, along with a means of injecting it - either a setter method or an alternate constructor. In the standard constructor for your class, instantiate a BufferedReaderFactory
and set the field accordingly. In your someMethod()
, call the makeBufferedReader()
method on the field, instead of using new
.
Your class is much more testable; because now, you can write a test that injects a mocked BufferedReaderFactory
to the object that you're testing, before calling someMethod()
. On that mock, you can stub the makeBufferedReader
method to throw the exception that you want.
Please add a comment if you want me to go into more detail on any of the steps above. You might also like to read my post on mocking object creation on the Mockito wiki; which is closely related to this.
But the most important message is that making your classes testable is really important, and you will reap the benefits of doing so many times over.
Upvotes: 1
Reputation: 692161
You're mocking a BufferedReader, but your method doesn't use your mock. It uses its own, new BufferedReader. You need to be able to inject your mock into the method.
It seems that inputStream
is a field of the class containing this method. So you could mock the inputStream instead and make it throw an IOException when its read()
method is called (by the InputStreamReader).
Upvotes: 9
Reputation: 14243
You can't mock BufferedReader
here since it's being created inside the method.
Try mocking inputStream
and throwing the exception from InputStream.read()
instead.
Upvotes: 2