Java 如何使用Mockito部分模拟HttpServletRequest
我在模拟一个HttpServletRequest,在servlet调用中,在请求中设置了新的值,因为使用相同的请求,我们将请求分派给某个jsp,所以请求对象被用作servlet的输入对象以及下一页的输出 我模拟了所有的输入参数,但是对于所有的request.setAttribute(),我的代码什么也不做,因为它是一个模拟类,如果我有Java 如何使用Mockito部分模拟HttpServletRequest,java,unit-testing,mockito,junit4,Java,Unit Testing,Mockito,Junit4,我在模拟一个HttpServletRequest,在servlet调用中,在请求中设置了新的值,因为使用相同的请求,我们将请求分派给某个jsp,所以请求对象被用作servlet的输入对象以及下一页的输出 我模拟了所有的输入参数,但是对于所有的request.setAttribute(),我的代码什么也不做,因为它是一个模拟类,如果我有 request.setAttribute(a,"10") System.out.println("a = " + request.getAttribute("a"
request.setAttribute(a,"10")
System.out.println("a = " + request.getAttribute("a"));
我得到空值是因为我没有为Request.getAttribute(“a”)提供任何行为,我不能,这是我下一页的响应,因此解释我需要2个行为我的请求对象因此进行部分模拟,到目前为止我无法对其进行监视或进行任何部分模拟。有什么想法吗
代码:
//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);
}
Mockito支持真正的部分模拟: 我认为它符合您的需要,并且在这方面很有用。例如
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
然后我可以调用myclass.method(request,response,…)并检查某些属性是否已正确设置到请求中,例如
MyBean attr = (MyBean) request.getAttribute(ATTRIBUTE_NAME));
// do my Assert.* stuff with 'attr'
MockHttpServletRequest和MockHttpServletResponse在mock(HttpServletRequest.class)失败的情况下可以正常工作,例如,您需要取回以前在业务逻辑中设置的请求属性的真实内容。您需要将属性存储到集合中:
// 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());
//用于存储属性键/值的集合
最终映射属性=新的ConcurrentHashMap();
//模拟集合属性
Mockito.doAnswer(新答案(){
@凌驾
公共Void应答(invocationmock调用)抛出可丢弃的{
String key=invocation.getArgumentAt(0,String.class);
对象值=invocation.getArgumentAt(1,Object.class);
属性。放置(键、值);
System.out.println(“put属性key=“+key+”,value=“+value”);
返回null;
}
}).when(request).setAttribute(Mockito.anyString(),Mockito.anyObject());
//模拟getAttribute
Mockito.doAnswer(新答案(){
@凌驾
公共对象应答(InvocationMock调用)抛出Throwable{
String key=invocation.getArgumentAt(0,String.class);
对象值=attributes.get(键);
System.out.println(“获取key=“+key+”:“+value”的属性值);
返回值;
}
}).when(request).getAttribute(Mockito.anyString());
你能展示你的模仿尝试吗?我又换了帖子。请参阅insertSumIntoDB(request.getAttribute(“sum”))这实际上是insertSumIntoDB(null),因为我没有给出request.getAttribute(“sum”)的行为;感谢您抽出时间,我无法监视HttpServletRequest,它是一个接口。spy在类上工作。很抱歉,引用是BrokerMockHttpServletRequest和MockHttpServletResponse是Spring的一部分。如果您不使用Spring,则无法使用它们。@Jimjarett您是对的;另一方面,包含MockHttpServlet…
类的spring测试依赖性相当轻量级(只需要spring core),因此可能值得将其纳入测试范围,以便进行更好的测试。