PowerMockito - 如何使用带有类型列表的whenNew()? [英] PowerMockito - How do I use whenNew() with a typed List?

查看:2934
本文介绍了PowerMockito - 如何使用带有类型列表的whenNew()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 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.

解决方案

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆