MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便, 最方便的是对于客户测试,不需要启动服务器即可测试我们的Rest Api。
SpringMVC编写Rest示例
Controller示例
@Controller
@RequestMapping(value = "/test")
public class TestWebController {
@ResponseBody
@RequestMapping(value = "/list", method = {RequestMethod.GET})
public List getMock(@RequestParam(name = "id", required = false, defaultValue = "l0") String id) {
return Arrays.asList("l1", "l2", "l3", id);
}
@ResponseBody
@RequestMapping(value = "/pust", method = {RequestMethod.POST})
public Object postMock(@RequestBody Object data) {
return ImmutableMap.<String, String>builder().put("data", JSON.toJSONString(data)).build();
}
@RequestMapping(value = "/view", method = {RequestMethod.GET})
public ModelAndView viewMock(){
return new ModelAndView("index");
}
}
复制代码
MockMvc测试Rest示例
- MockMvc基础交互示例
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:context/spring-context.xml", "classpath:context/spring-mvc.xml"})
@WebAppConfiguration(value = "src/main/webapp")
public class TestController {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void test01() throws Exception {
MvcResult mvcResult = this.mockMvc.perform(MockMvcRequestBuilders.get("/test/list")
.cookie(new Cookie("token", "F3AF5F1D14F534F677XF3A00E352C")) // 登录授权
.accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
.andExpect(handler().handlerType(TestWebController.class)) // 验证执行的控制器类型
.andExpect(handler().methodName("getMock")) // 验证执行的方法名
.andExpect(status().isOk()) // 验证执行状态
.andDo(print()) // 打印交互信息
.andReturn();
System.out.println(mvcResult.getResponse().getContentAsString());
}
}
复制代码
MockMvc可以对controller中的一次调用进行模拟; 1、mockMvc.perform执行一个请求; 2、MockMvcRequestBuilders.get(urlTemplate, urlMultiParams)构造一个请求 3、ResultActions.andExpect添加执行完成后的断言 4、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。 5、ResultActions.andReturn表示执行完成后返回相应的结果。
执行结果:
["l1","l2","l3","l0"]
复制代码
交互信息:
MockHttpServletRequest:
HTTP Method = GET
Request URI = /test/list
Parameters = {}
Headers = {Accept=[application/json;charset=UTF-8]}
Handler:
Type = com.simple.example.web.TestWebController
Method = public java.util.List com.simple.example.web.TestWebController.getMock(java.lang.String)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = ["l1","l2","l3","l0"]
Forwarded URL = null
Redirected URL = null
Cookies = []
复制代码
- MockMvc请求参数示例
@Test
public void test02() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/test/list?id={id}", "模板参数")
.accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
.andExpect(handler().handlerType(TestWebController.class)) // 验证执行的控制器类型
.andExpect(handler().methodName("getMock")) // 验证执行的方法名
.andExpect(status().isOk()) // 验证执行状态
.andDo(print()) // 打印交互信息
.andReturn();
System.out.println(mvcResult.getResponse().getContentAsString());
}
复制代码
执行结果:
["l1","l2","l3","模板参数"]
复制代码
- MockMvc测试Post示例
@Test
public void test() throws Exception {
MvcResult mvcResult = mockMvc.perform(post("/test/pust")
.contentType(MediaType.APPLICATION_JSON)
.content(JSON.toString(Arrays.asList("p1", "p2")))
.accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
.andExpect(handler().handlerType(TestWebController.class)) // 验证执行的控制器类型
.andExpect(handler().methodName("getMock")) // 验证执行的方法名
.andExpect(status().isOk()) // 验证执行状态
.andDo(print()) // 打印交互信息
.andReturn();
System.out.println(mvcResult.getResponse().getContentAsString());
}
复制代码
交互信息
MockHttpServletRequest:
HTTP Method = POST
Request URI = /test/pust
Parameters = {}
Headers = {Content-Type=[application/json], Accept=[application/json;charset=UTF-8]}
Handler:
Type = com.simple.example.web.TestWebController
Method = public java.lang.Object com.simple.example.web.TestWebController.postMock(java.lang.Object)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = {"data":"[\"p1\",\"p2\"]"}
Forwarded URL = null
Redirected URL = null
Cookies = []
复制代码
执行结果:
{"data":"[\"p1\",\"p2\"]"}
复制代码
- 测试视图页
@Test
public void test05() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/test/view"))
.andExpect(view().name("index")) //验证视图页面
.andExpect(model().hasNoErrors()) //验证页面没有错误
.andExpect(status().isOk()) //验证状态码
.andDo(print())
.andReturn();
System.out.println(mvcResult.getModelAndView().getViewName());
}
复制代码
执行结果:
index
复制代码