简体   繁体   中英

how to throw IOException while reading a file using Mockito?

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 :(

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM