如何用 mockito 模拟静态方法来做单元测试
How to mock the static method with mockito to do unit test
我有这样的方法
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......
}
我想模拟 Recorder.getRecorder() 并执行 when(Recorder.getRecorder()).thenReturn(null) 之类的操作并测试是否抛出 503 异常。但是 getRecorder() 是一个静态方法。我知道 Mockito 不能模拟静态方法,但我仍然想知道是否可以更改一些代码,使其在不使用 Powermock 或其他库的情况下可测试。
如果我mock Recorder,是不是要把方法改成post(String json, Recorder recorder)?否则,我怎样才能使这个模拟与方法交互?
如果您想在不使用模拟静态方法的库(例如 Powermock)的情况下模拟 getRecorders()
行为,那么您必须从 post()
内部提取静态调用。为此有几个选项:
将EventList
传递给post()
public post(String json, EventList list) {
...
}
将EventList
注入包含post()
的class
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");
}
}
}
将静态方法调用隐藏在另一个class中并将thatclass的实例注入post()
或class 包含 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) null EventList
; (2) 一个空的 EventList
...从而允许您测试 'throw a 503 exception' 行为。
使用第三种方法,您可以使用 Mockito 模拟 RecorderFactory
到 return 的行为 (1) null EventList
; (2) 一个空的 EventList
...从而允许您测试 'throw a 503 exception' 行为。
我有这样的方法
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......
}
我想模拟 Recorder.getRecorder() 并执行 when(Recorder.getRecorder()).thenReturn(null) 之类的操作并测试是否抛出 503 异常。但是 getRecorder() 是一个静态方法。我知道 Mockito 不能模拟静态方法,但我仍然想知道是否可以更改一些代码,使其在不使用 Powermock 或其他库的情况下可测试。
如果我mock Recorder,是不是要把方法改成post(String json, Recorder recorder)?否则,我怎样才能使这个模拟与方法交互?
如果您想在不使用模拟静态方法的库(例如 Powermock)的情况下模拟 getRecorders()
行为,那么您必须从 post()
内部提取静态调用。为此有几个选项:
将
EventList
传递给post()
public post(String json, EventList list) { ... }
将
的classEventList
注入包含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"); } } }
将静态方法调用隐藏在另一个class中并将thatclass的实例注入
post()
或class 包含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) null EventList
; (2) 一个空的 EventList
...从而允许您测试 'throw a 503 exception' 行为。
使用第三种方法,您可以使用 Mockito 模拟 RecorderFactory
到 return 的行为 (1) null EventList
; (2) 一个空的 EventList
...从而允许您测试 'throw a 503 exception' 行为。