如何使用Mockito模拟静态方法以进行单元测试

时间:2018-12-14 02:36:15

标签: java unit-testing junit mockito static-methods

我有这样的方法。

 public Response post(String json) {

   EventList list = Recorder.getRecorders();
   if (null == list || list.isEmpty()) {
     throw new ServiceUnavailableException("An Recorder is either not configured");
  }
  String targetIUrl = list.getNext().getBase();
  String targetV2Url = targetUrl + "/v2";

 // other processes......
}
  1. 我想模拟Recorder.getRecorder()并执行when(Recorder.getRecorder())。thenReturn(null)之类的操作,并测试是否抛出503异常。但是getRecorder()是静态方法。我知道Mockito无法模拟静态方法,但是我仍然想知道是否有可能在不使用Powermock或其他库的情况下更改一些可测试的代码。

  2. 如果我模拟记录器,是否必须将方法更改为post(字符串json,记录器记录器)?否则,如何使该模拟与该方法交互?

1 个答案:

答案 0 :(得分:1)

如果您想模拟getRecorders()的行为而无需使用模拟静态方法的库(例如Powermock),则必须从post()内部提取静态调用。有几种选择:

  1. EventList传递到post()

    public post(String json, EventList list) {
        ...
    }
    
  2. EventList注入到包含post()

    的类中
    public class TheOneThatContainsThePostMethod {
        private EventList eventList;
    
        public TheOneThatContainsThePostMethod(EventList eventList) {
            this.eventList = eventList;
        }
    
        public post(String json) {
            if (null == this.eventList || this.eventList.isEmpty()) {
                throw new ServiceUnavailableException("An Recorder is either not configured");
            }
        }
    }
    
  3. 将静态方法调用隐藏在另一个类中,并将那个类的实例注入post()或包含post()的类中。例如:

    public class RecorderFactory {
        public EventList get() {
            return Recorder.getRecorders();
        }
    }
    
    public class TheOneThatContainsThePostMethod {
        private RecorderFactory recorderFactory;
    
        public TheOneThatContainsThePostMethod(RecorderFactory recorderFactory) {
            this.recorderFactory = recorderFactory;
        }
    
        public post(String json) {
            EventList list = recorderFactory.getRecorders();
            ...
        }
    }
    
    // Or ...
    
    public post(String json, RecorderFactory recorderFactory) {
        EventList list = recorderFactory.getRecorders();
        ...
    }
    

使用前两种方法,您的测试可以简单地调用post(),从而提供(1)空EventList; (2)一个空的EventList ...从而使您可以测试“抛出503异常”行为。

使用第三种方法,您可以使用Mockito模拟RecorderFactory的行为以返回(1)空EventList; (2)一个空的EventList ...从而使您可以测试“抛出503异常”行为。