简体   繁体   English

如何在使用Mockito读取文件时抛出IOException?

[英]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. 我必须使用Mockito为一个方法抛出一个IOException ,它正在读取一个输入流,如下所示。 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. 你在嘲笑BufferedReader,但你的方法不使用你的模拟。 It uses its own, new BufferedReader. 它使用自己的新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. 看起来inputStream是包含此方法的类的字段。 So you could mock the inputStream instead and make it throw an IOException when its read() method is called (by the InputStreamReader). 所以你可以改为模拟inputStream,并在调用read()方法(由InputStreamReader)时抛出一个IOException。

You can't mock BufferedReader here since it's being created inside the method. 你不能在这里模拟BufferedReader ,因为它是在方法中创建的。

Try mocking inputStream and throwing the exception from InputStream.read() instead. 尝试模拟inputStream并从InputStream.read()抛出异常。

The way that I would recommend is to have an extra class that looks after the creation of the BufferedReader . 我建议的方法是有一个额外的类来管理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. 现在,将BufferedReaderFactory类型的私有字段添加到您正在测试的类中,同时添加一个注入它的方法 - setter方法或备用构造函数。 In the standard constructor for your class, instantiate a BufferedReaderFactory and set the field accordingly. 在类的标准构造函数中,实例化BufferedReaderFactory并相应地设置字段。 In your someMethod() , call the makeBufferedReader() method on the field, instead of using new . someMethod() ,在字段上调用makeBufferedReader()方法,而不是使用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() . 因为现在,您可以编写一个测试,在调用someMethod()之前将someMethod() BufferedReaderFactory注入您正在测试的对象。 On that mock, you can stub the makeBufferedReader method to throw the exception that you want. 在那个makeBufferedReader ,你可以存根makeBufferedReader方法来抛出你想要的异常。

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; 您可能还想在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. 但最重要的信息是,让你的课程可测试是非常重要的,你将获得这么多次这样做的好处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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