![](/img/trans.png)
[英]Mocking a static Method in Abstract class using Mockito
[英]Mocking of static field that is a class with Mockito
我的 Utils class 有一个依赖于外部资源(例如,数据库连接)的 init 方法,我没有成功 mocking 和 Mockito。Utils 似乎可以跨我的应用程序实例共享,因此被声明为 static(即 class变量)在
public class EmailNotificationWorkItemHandler extends AbstractLogOrThrowWorkItemHandler {
private static Utils utils = new Utils();
public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
// Throw an error due to many missing parameters on the workitem
String id= (String) workItem.getParameter("ID");
...
try {
RequiredParameterValidator.validate(this.getClass(), workItem);
...
} catch (Throwable e) {
utils.insertErrors(id, errorCode, errorMessage, e.getStackTrace(), -1L); // testing this method called
}
...
}
我意识到我可以为 Utils 使用依赖注入,但我正在避免使用Spring。 关于mocking static 字段的帖子让我觉得我很接近:
@Test
public void executeWorkItemMissingParametersTest() {
Utils mockUtils = mock(Utils.class);
WorkItemManager mockWorkItemMgr = mock(WorkItemManager.class);
EmailNotificationWorkItemHandler mockWorkItemHandler = mock(EmailNotificationWorkItemHandler.class);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
System.out.println("called with arguments: " + Arrays.toString(args));
return null;
}
}).when(mockUtils).insertErrors(any(), any(), any(), any(), anyLong());
try {
doAnswer(new Answer<Void>() { // Unfinished stubbing detected
public Void answer(InvocationOnMock invocation) {
return null;
}
}).when(mockUtils);
Utils.init();
} catch (Exception e) {
System.out.println("In mocking of Utils.init() " + e.getLocalizedMessage());
}
WorkItemImpl workItem = new WorkItemImpl();
workItem.setParameter("ID", "1111-AAAA");
// Lots of required parameters removed to cause an exception and insertErrors to be called
mockWorkItemHandler.executeWorkItem(workItem, mockWorkItemMgr);
verify(mockUtils).insertErrors(any(), any(), contains("RequiredParameterValidator"), any(), anyLong());
}
但是在 mockWorkItemHandler 中使用和调用了一个真实的 Utils 实例 - 而不是模拟的 Utils - 并且在上面标记的地方发生了“检测到未完成的存根”异常。 我的目标是测试代码中注释的 utils.insertErrors 的调用,并在没有 Utils 的副作用的情况下执行此操作。 我在模拟中缺少什么(1)使用模拟的 Utils(没有副作用,例如数据库连接)和(2)测试调用 mockWorkItemHandler 的 utils.insertErrors 来记录丢失的参数?
请注意,我已经展示了似乎是 EmailNotificationWorkItemHandler 和 Utils 的所有相关部分。
这是一个使用 mockito 内联的 mocking 构造调用的简单示例。 为了启用 mockito-inline,您可以参考此答案,因为 mockito 默认关闭它。您可以在您的用例中使用它,它应该可以解决您的问题。
消费者 Class
public class ConsumerClass {
Logger logger = LoggerFactory.getLogger(ConsumerClass.class);
private static final Utils utils = new Utils();
public String callUtilMethod(){
logger.info("ConsumerClass callUtilMethod");
return utils.helloWorld();
}
}
工具
public class Utils {
Logger logger = LoggerFactory.getLogger(Utils.class);
public String helloWorld() {
logger.info("Utils class Hello World");
return "This is from Utils";
}
}
测试用例
@Test
void testConsumerClass() {
try (MockedConstruction<Utils> mocked = Mockito.mockConstruction(Utils.class, (mock, context) -> {
Mockito.when(mock.helloWorld()).thenReturn("This is from Mock");
})) {
ConsumerClass consumerClass = new ConsumerClass();
Assertions.assertEquals("This is from Mock", consumerClass.callUtilMethod());
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.