Java 如何使用 Mockito 部分模拟 HttpServletRequest

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22714359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 17:27:05  来源:igfitidea点击:

How to partially mock HttpServletRequest using Mockito

javaunit-testingmockitojunit4

提问by Vivek

i am mocking a HttpServletRequest , in servlet call there are new values getting set in request because using same request we are dispaching request to some jsp so request object is used as a input object to servlet as well as output for next page.

我正在模拟 HttpServletRequest ,在 servlet 调用中,请求中设置了新值,因为使用相同的请求,我们将请求发送到某些 jsp,因此请求对象用作 servlet 的输入对象以及下一页的输出。

i mocked all input parameters , but for all request.setAttribute() , my code is doing nothing as it's a mocked class , say if i have

我模拟了所有输入参数,但对于所有 request.setAttribute() ,我的代码什么都不做,因为它是一个模拟类,比如我有

request.setAttribute(a,"10")
System.out.println("a = " + request.getAttribute("a"));

i get null cuz i haven't given any behavious for Request.getAttribute("a") , and i can't , it's my response for next page , so that explain i need 2 behaviour my request object thus partial mocking , and i am unable to spy or do any partial mocking on it so far. any ideas?

我得到 null 因为我没有对 Request.getAttribute("a") 给出任何行为,而且我不能,这是我对下一页的响应,所以解释我需要 2 行为我的请求对象因此部分嘲笑,我到目前为止,我无法监视或对其进行任何部分嘲笑。有任何想法吗?

Code :

代码 :

 //Testcase
   Myservlet.java
public void doPost(request,response)
    {
         String a = request.getAttribute("a");
         String b = request.getAttribute("b");
         int sum = Integer.parseInt(a) + Integer.parseInt(b);
         request.setAttribute("sum",sum);
         //well in this example i can use sum what i calculated but in real senario i can't , i have to use request.getAttribute("sum")
         insertSumIntoDB(request.getAttribute("sum"));
    }
    }



  //testMyservlet.java
   @test
public void testServlet()
 {
 HttpServletRequest request = mock(HttpServletRequest.class);
     HttpServletResponse response = mock(HttpServletResponse.class);
when(request.getAttribute(a)).thenReturn("10");
when(request.getAttribute(b)).thenReturn("20");
new Myservlet(request,response);
}

采纳答案by Aure77

You need to store attributes into a collection :

您需要将属性存储到集合中:

// Collection to store attributes keys/values
final Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();     

// Mock setAttribute
Mockito.doAnswer(new Answer<Void>() {
    @Override
    public Void answer(InvocationOnMock invocation) throws Throwable {
        String key = invocation.getArgumentAt(0, String.class);
        Object value = invocation.getArgumentAt(1, Object.class);
        attributes.put(key, value);
        System.out.println("put attribute key="+key+", value="+value);
        return null;
    }
}).when(request).setAttribute(Mockito.anyString(), Mockito.anyObject());

// Mock getAttribute
Mockito.doAnswer(new Answer<Object>() {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
        String key = invocation.getArgumentAt(0, String.class);
        Object value = attributes.get(key);
        System.out.println("get attribute value for key="+key+" : "+value);
        return value;
    }
}).when(request).getAttribute(Mockito.anyString());

回答by Thomas

Mockito supports real partial mock : http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#16

Mockito 支持真正的部分模拟:http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#16

I think it fits your needs

我认为它符合您的需求

回答by medveshonok117

Spring's MockHttpServletRequestand MockHttpServletResponseare useful for that purpose. E.g.

Spring 的MockHttpServletRequestMockHttpServletResponse对此很有用。例如

    MockHttpServletRequest request = new MockHttpServletRequest();
    MockHttpServletResponse response = new MockHttpServletResponse();
    request.addHeader(HttpHeaders.HOST, "myhost.com");
    request.setLocalPort(PORT_VALID); // e.g. 8081
    request.setRemoteAddr(REQUEST_IP); // e.g. 127.0.0.1

then I can call myclass.method(request, response, ...)and check whether some attribute has been correctly set into the request, e.g.

然后我可以调用myclass.method(request, response, ...)并检查某些属性是否已正确设置到请求中,例如

    MyBean attr = (MyBean) request.getAttribute(ATTRIBUTE_NAME));
    // do my Assert.* stuff with 'attr'

MockHttpServletRequest and MockHttpServletResponse work fine where mock(HttpServletRequest.class)fails, for instance where you need to get back the real content of a request attribute which has been previously set within your business logic.

MockHttpServletRequest 和 MockHttpServletResponse 在mock(HttpServletRequest.class)失败的情况下工作正常,例如,您需要取回先前在业务逻辑中设置的请求属性的真实内容。