使用MockMvc模拟应用集成环境进行测试。
@WebAppConfiguration必须标识出来,表示测试的环境为Web环境。
SpringMVC 测试 mockMVC——集成Web环境方式
测试流程
- 准备测试环境
- 通过MockMvc执行请求
- 添加验证断言
- 添加结果处理器
- 获取MvcResult进行自定义断言/进行下一步的异步请求
- mockMvc.perform:执行一个RequestBuilder请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理;
- MockMvcRequestBuilders.get("/user/findAll):构造一个请求
- ResultActions.andExpect:添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确;
- ResultActions.andDo:添加ResultHandler结果处理器,比如调试时打印结果到控制台;
- ResultActions.andReturn:最后返回相应的MvcResult;然后进行自定义验证/进行下一步的异步处理;
测试示例1
测试对象:
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/findAll")
public ModelAndView findAll(ModelAndView mv) {
List<User> userList = userService.findAll();
userList.forEach(User::toString);
mv.addObject("list", userList); //添加传递的数据
mv.setViewName("list"); //找View层中的list.jsp
return mv;
}
}
测试启动类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:*.xml")
@WebAppConfiguration
public class TestController {
@Autowired
UserController userController;
@Test
public void testUserController() throws Exception {
MockMvc mock = MockMvcBuilders.standaloneSetup(userController).build();
mock.perform(get("/user/findAll"))
.andExpect(status().isOk())
.andExpect(forwardedUrl("list"));
}
}
MockMvcBuilders
用于构造MockMvc的构造器,主要有两种实现:
- DefaultMockMvcBuilder 集成测试整个Web环境
- addFilters/addFilter 可增加过滤器
- defaultRequest 默认的RequestBuilder,每次执行时会合并到自定义的RequestBuilder中,即提供公共请求数据的
- alwaysExpect 定义每次执行请求时都进行验证的规则
- alwaysDo 定义每次请求时都进行结果处理
- dispatchOptions DispatcherServlet是否分发OPTIONS请求方法到控制器
- StandaloneMockMvcBuilder 继承了DefaultMockMvcBuilder,可独立测试指定Controller
具体介绍看 springmvc之单元测试(MockMvc)-独立测试
MockHttpServletRequestBuilder
Http请求方法的构造器
MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables):根据uri模板和uri变量值得到一个GET请求方式的
MockHttpServletRequestBuilder;如**get("/user/{id}", 1L)**;
MockHttpServletRequestBuilder post(String urlTemplate, Object... urlVariables):同get类似,但是是POST方法;
MockHttpServletRequestBuilder put(String urlTemplate, Object... urlVariables):同get类似,但是是PUT方法;
MockHttpServletRequestBuilder delete(String urlTemplate, Object... urlVariables) :同get类似,但是是DELETE方法;
MockHttpServletRequestBuilder options(String urlTemplate, Object... urlVariables):同get类似,但是是OPTIONS方法;
MockMvcResultMatchers
Http请求结果的验证器
HandlerResultMatchers handler():请求的Handler验证器,比如验证处理器类型/方法名;此处的Handler其实就是处理请求的控制器;
RequestResultMatchers request():得到RequestResultMatchers验证器;
ModelResultMatchers model():得到模型验证器;
ViewResultMatchers view():得到视图验证器;
FlashAttributeResultMatchers flash():得到Flash属性验证;
StatusResultMatchers status():得到响应状态验证器;
HeaderResultMatchers header():得到响应Header验证器;
CookieResultMatchers cookie():得到响应Cookie验证器;
ContentResultMatchers content():得到响应内容验证器;
JsonPathResultMatchers jsonPath(String expression, Object ... args)/ResultMatcher jsonPath (String expression, Matcher matcher):得到Json表达式验证器;
XpathResultMatchers xpath(String expression, Object... args)/XpathResultMatchers xpath(String expression, Map<string, string=""> namespaces, Object... args):得到Xpath表达式验证器;
ResultMatcher forwardedUrl(final String expectedUrl):验证处理完请求后转发的url(绝对匹配);
ResultMatcher forwardedUrlPattern(final String urlPattern):验证处理完请求后转发的url(Ant风格模式匹配,@since spring4);
ResultMatcher redirectedUrl(final String expectedUrl):验证处理完请求后重定向的url(绝对匹配);
ResultMatcher redirectedUrlPattern(final String expectedUrl):验证处理完请求后重定向的url(Ant风格模式匹配,@since spring4)
测试示例2
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:*.xml")
@WebAppConfiguration
public class TestController {
@Autowired
WebApplicationContext wac;
MockMvc mock;
@Autowired
UserController userController;
@BeforeClass
public static void init() {
System.out.println("@BeforeClass");
}
@Before
public void initMock() {
mock = MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test
public void testUserController() throws Exception {
MvcResult result = mock.perform(get("/user/findAll"))
.andExpect(status().isOk())
.andExpect(forwardedUrl("/WEB-INF/pages/list.jsp"))
.andDo(print())
.andReturn();
System.out.println(result.getModelAndView().toString());;
}
}