PowerMockito - How do I use whenNew() with a typed List?

走远了吗. 提交于 2019-12-07 12:36:55

问题


I want PowerMockito to return my empty array-list of Foos 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.


回答1:


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.



来源:https://stackoverflow.com/questions/19104647/powermockito-how-do-i-use-whennew-with-a-typed-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!