PowerMockito - 如何使用带有类型列表的whenNew()? [英] PowerMockito - How do I use whenNew() with a typed List?
问题描述
当 new ArrayList< Foo>()
时,我希望PowerMockito返回我的空数组列表 Foo
被称为,但我不知道如何构建声明。具体来说,我希望新的ArrayList< AnyOtherType>()
来创建一个新的列表,如同正常情况一样。
的ArrayList<富> 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);
)。通常在我们的应用程序中,我们将数据放置在会话级变量中。但是由于这个方法被一次调用多次,并且结果会被写入页面,所以每个数据片段都会被存储在请求中:
request.setAttribute(inspectionAjaxDetails,详情);
所以我需要一些方法来获取详情
,这是一个类型化的ArrayList,当 request
被模拟时。
简短的回答是:你不能。正如Matt Lachman在评论中指出的那样,你不能捕获类型的泛型,所以你不能得到 List< Foo>
c> List< Bar> 和 List< AnyOtherType>
。因为集合的使用太多了,所以尝试使用PowerMock捕获它们几乎总是一个坏主意。
在我的情况下,我需要获得一个给定的List在我试图测试的方法中作为一个属性(映射为< String,Object>
)来模拟 HttpServletRequest
。我必须找到一个不同的解决方案。在我的例子中,它创建了一个非匿名的 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类实现答案< 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];
返回attributes.get(key);
} else if(getParameter.equals(methodName)){
String key =(String)args [0];
返回parameters.get(key);
}
返回null;
}
剩下的只是几个Maps和getters和setters。
I want PowerMockito to return my empty array-list of Foo
s when new ArrayList<Foo>()
is called, but I am not sure how to construct the statement. Specifically, I want new ArrayList<AnyOtherType>()
to create a new list as normal.
ArrayList<Foo> fooList = new ArrayList<Foo>();
PowerMockito.whenNew(ArrayList.class).withParameterTypes(Foo.class).thenReturn(fooList);
^ Here's basically what I have, but .withParameterTypes(Foo.class)
does not allow me to follow with a .thenReturn()
. My only option is withArguments(firstArgument, additionalArguments)
.
Is this possible with PowerMock, and if so, how do I construct it?
EDIT:
Ok, the underlying problem is I need to get the result of the method I'm trying to test, but I had to mock the request, and the list is placed in the request at the end of the method I'm trying to test.
inspectionAction.viewInspectionDetailsAjax(mapping, form, request, response);
This method pulls a couple of parameters from the request, which is mocked (Mockito.mock(HttpServletRequest.class);
). Usually in our app we place data on a session-level variable. But since this method is called several times at once and the results ajax'd into the page, each piece of data is stored in the request instead:
request.setAttribute("inspectionAjaxDetails", details);
So I need some way to get details
, which is a typed ArrayList, when request
is mocked.
The short answer is: You can't. As Matt Lachman pointed out in the comments, you can't capture the generics of a type, so you can't get List<Foo>
without also getting List<Bar>
and List<AnyOtherType>
. Because collections are used so heavily, it is almost always a bad idea to try to capture them with PowerMock.
In my case, I needed to get a List that was given to a mocked HttpServletRequest
as an attribute (mapped <String, Object>
) in the method I was trying to test. I had to find a different solution. In my case, it was to create a non-anonymous implementation of Answer
that I could retrieve values from after the method was run. My Mockito call looked like this:
RequestAnswer requestAnswer = new RequestAnswer();
Mockito.doAnswer(requestAnswer).when(request).setAttribute(Matchers.anyString(), Matchers.anyObject());
ArrayList<Foo> details = (ArrayList<Foo>) requestAnswer.getAttribute("foo");
My RequestAnswer class implements Answer<Object>
, and its most important method looks like this:
@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;
}
The rest was just a couple of Maps and getters and setters.
这篇关于PowerMockito - 如何使用带有类型列表的whenNew()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!