我希望PowerMockito在调用Foo
时返回new ArrayList<Foo>()
的空数组列表,但我不确定如何构造语句。具体来说,我希望new ArrayList<AnyOtherType>()
正常创建一个新列表。
ArrayList<Foo> fooList = new ArrayList<Foo>();
PowerMockito.whenNew(ArrayList.class).withParameterTypes(Foo.class).thenReturn(fooList);
^这基本上就是我所拥有的,但.withParameterTypes(Foo.class)
不允许我使用.thenReturn()
。我唯一的选择是withArguments(firstArgument, additionalArguments)
。
PowerMock是否可以实现,如果是,我该如何构建它?
编辑:
好的,潜在的问题是我需要获取我正在尝试测试的方法的结果,但我不得不模拟请求,并且列表放在方法结束时的请求中我是试图测试。
inspectionAction.viewInspectionDetailsAjax(mapping, form, request, response);
此方法从请求中提取了一些参数,这些参数被模拟(Mockito.mock(HttpServletRequest.class);
)。通常在我们的应用程序中,我们将数据放在会话级变量上。但是,由于这个方法一次被调用多次并且结果ajax进入页面,所以每个数据都存储在请求中:
request.setAttribute("inspectionAjaxDetails", details);
所以当模拟details
时,我需要一些方法来获取request
,这是一个类型化的ArrayList。
答案 0 :(得分:2)
简短的回答是:你做不到。正如Matt Lachman在评论中指出的那样,您无法捕获类型的泛型,因此如果没有获得List<Foo>
和List<Bar>
,则无法获取List<AnyOtherType>
。由于集合的使用非常频繁,尝试使用PowerMock捕获它们几乎总是一个坏主意。
在我的情况下,我需要在我尝试测试的方法中获取一个作为属性(映射HttpServletRequest
)的模拟<String, Object>
的List。我必须找到一个不同的解决方案。在我的例子中,它是创建Answer
的非匿名实现,我可以在方法运行后检索值。我的Mockito电话看起来像这样:
RequestAnswer requestAnswer = new RequestAnswer();
Mockito.doAnswer(requestAnswer).when(request).setAttribute(Matchers.anyString(), Matchers.anyObject());
ArrayList<Foo> details = (ArrayList<Foo>) requestAnswer.getAttribute("foo");
我的RequestAnswer类实现Answer<Object>
,其最重要的方法如下所示:
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
String methodName = invocation.getMethod().getName();
if ("setAttribute".equals(methodName)) {
String key = (String) args[0];
Object value = args[1];
attributes.put(key, value);
} else if ("getAttribute".equals(methodName)) {
String key = (String) args[0];
return attributes.get(key);
} else if ("getParameter".equals(methodName)) {
String key = (String) args[0];
return parameters.get(key);
}
return null;
}
剩下的就是几张地图,吸气鬼和制定者。