![](/img/trans.png)
[英]Junit Framework Unit Tests : Mockito.doNothing() doesn't work as expected while mocking void methods
[英]Mocking void unit tests with Mockito
在对我的应用程序进行单元测试时遇到很多问题,请帮助解决我最简单的问题 - mocking 无效方法,根据一些堆栈溢出文章和文章中的常见参考。 我在 JBPM 应用程序 WorkItemHandler 中的 Java 代码遵循以下模式
public class EmailNotificationWorkItemHandler() extends AbstractLogOrThrowWorkItemHandler {
private static Utils utils = new Utils() ;
public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
if (<condition>) {
utils.insertAmsErrors(<param>, <param>, <param>, <param>, <param>);
return;
}
....
try {
RequiredParameterValidator.validate(this.getClass(), workItem);
...
}
我一直在尝试存根 Utils 及其 insertAmsErrors 方法来测试稍后在 executeWorkItem 中使用的 RequiredParameterValidator.validate。 这些参考暗示对 utils 及其 insertAmsErrors 方法的无效调用可能是一个非常基本的存根
Utils mockUtils = mock(Utils.class);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
//Mock mock = (Mock) invocation.getMock(); Doesn't solve NPE
return null;
}
}).when(mockUtils).insertAmsErrors(any(), any(), any(), any(), any()); // NPE here
但存根在“NPE here”处抛出 null 指针异常。 Utils.insertAmsErrors 签名是
public void insertAmsErrors(String id, ErrorCode error, String errorMsg,
StackTraceElement [] stackTrace, long processId)
根据同一帖子中的另一个答案,我还考虑过使用间谍,但我的单元测试不是在 Utils 的实例上调用 insertAmsErrors,而是 EmailNotificationWorkItemHandler 中的 executeWorkItem 正在进行这样的调用。
我应该如何正确模拟 Utils class 及其 insertAmsErrors 方法,以便我可以在 executeWorkItem 中测试 RequiredParameterValidator.validate?
该问题与您 mocking 无效方法这一事实无关。 问题在于您对any()
方法的使用。
when(mockUtils).insertAmsErrors(any(), any(), any(), any(), any());
第 5 个必需参数是long
类型,因此您应该使用专用的anyLong()
方法来代替它。 这适用于所有原始类型: anyInt()
用于int
参数, anyBoolean()
用于boolean
参数等等...
这背后的原因是 Mockito 的any()
方法在设计上返回null
,在尝试拆箱时引发 NPE。 有关它的更多详细信息,请参阅此相关答案。
(旁注)另一个潜在的问题可能是由于您的utils
字段是static
, private
且具有硬编码依赖项。 这不是存根的好目标,您可能应该通过例如使字段非静态然后注入依赖项来重新考虑这一点。
public class EmailNotificationWorkItemHandler() extends AbstractLogOrThrowWorkItemHandler {
private Utils utils;
public EmailNotificationWorkItemHandler(Utils utils){
this.utils = utils;
}
...
}
这样您就可以在单元测试期间通过模拟的 object。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.