使用MockMvc测试Controller

叁歲伎倆 2021-09-27 11:50 539阅读 0赞

1. 概述

对模块进行集成测试时,希望能够通过输入URLcontroller进行测试,如果通过启动服务器,建立http client进行测试,这样会使得测试的变得的很麻烦,比如: 启动速度慢、测试验证不方便、依赖网络环境等,这样会导致测试无法进行,为了可以对Controller进行测试,可以通过引入MockMVC进行解决.

2.运行配置

  • 引入的jar :

    1. <!-- 单元测试 -->
    2. <dependency>
    3. <groupId>junit</groupId>
    4. <artifactId>junit</artifactId>
    5. <version>4.12</version>
    6. </dependency>
    7. <!-- spring test -->
    8. <dependency>
    9. <groupId>org.springframework</groupId>
    10. <artifactId>spring-test</artifactId>
    11. <version>4.3.5.RELEASE</version>
    12. </dependency>
  • 用到的注解 :

    1.@RunWith(SpringJunit4ClassRunner.class) : 表示使用Spring Test组件进行单元测试 .

    2.@WebAppConfiguration : 使用这个Annotaion会在跑单元测试时真实的启动一个web服务,然后开始调用ControllerRestful API,待单元测试跑完之后再将web服务停掉.

    3.@ContextConfiguration({ "classpath:spring-mvc.xml", "classpath:applicationContext.xml"}) : 指定Bean的配置文件信息,可以有多种方式,这个例子使用的文件路径形式,如果有多个配置文件,可以将括号中的信息配置为一个字符串数组来表示.

3. 基本框架

**测试 : **

  1. package com.makesailing.neo; import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; 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.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration({ "classpath:spring-mvc.xml", "classpath:applicationContext.xml"}) public class BaseControllerTest { // 注入web环境的ApplicationContext容器 @Autowired protected WebApplicationContext webApplicationContext; /** * 模拟mvc测试对象 */ protected MockMvc mockMvc; /** * 所有测试方法执行之前执行该方法 */ @Before // 这个注解的作用,在每个方法之前都会执行一遍 public void before() { //获取mockmvc对象实例 mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); } }
  2. // 配置事务的回滚,对数据库的增删改都会回滚,便于测试用例的循环利用 @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) @Transactional public class UserControllerTest extends BaseControllerTest { /** * Method: getUserDetailById(@PathVariable(name = "id") Long id) */ @Test public void testGetUserDetailById() throws Exception { RequestBuilder request = null; request = get('v1/user/{ id}/detail", 1); String responseString = mockMvc.perform(request) .andExpect(status().isOk()) // 返回的状态是200 .andDo(print()) // 打印出请求和相应的内容 .andReturn().getResponse().getContentAsString(); // 将数据转换为字符串 Assert.assertNotNull(responseString); System.out.println(responseString); } }

Controller层 :

  1. @RestController public class UserController { @Autowired private UserService userService; @GetMapping("v1/user/{id}/detail") public String getUserDetailById(@PathVariable(name = "id") Long id) { User user = userService.getUserDetailById(id); return JSON.toJSONString(user); } }

代码解析 :

  • perform:执行一个RequestBuider请求,自动执行SpringMvc的流程并映射到相应的控制器执行处理
  • get: 声明一个发送get请求的方法. public static MockHttpServletRequestBuilder get(String urlTemplate, Object... uriVars) { return new MockHttpServletRequestBuilder(HttpMethod.GET, urlTemplate, uriVars);}这是个静态方法,可以直接导入,根据uri模版和uri的变量值得到一个get请求的方法. 另外提供了其他的请求方法, 如:postputdelete 等.
  • andExperct: 添加ResultMatcher验证规则,验证perform执行完成后的结果是否正确(对返回的数据进行判断)
  • andDo: 添加ResultHandler结果处理器,比如调试打印结果到控制台print()
  • andReturn: 最后返回相应的MvcResult,然后进行自定义验证/进行下一步的异步处理.

注意如果是postput 测试,Controller使用@RequestBody User user进行接收,那么测试时也需要使用json格式数据,如下 :

  1. /** * Method: saveUser(@RequestBody User user) */ @Test public void testSaveUser() throws Exception { User user = new User(); user.setEmail("12345678@qq.com"); user.setUsername("jack"); user.setPassword("123456"); user.setRole("root"); user.setStatus(1); user.setRegtime(new Date()); //user.setRegip("127.0.0.1"); String content = JSON.toJSONString(user); String response = mockMvc.perform( post(Urls.User.SAVE_USER).contentType(MediaType.APPLICATION_JSON_UTF8).content(content)) .andDo(print()) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(); Assert.assertNotNull(response); Assert.assertNotEquals(response,""); System.out.println(response); } /** * Method: updateUser(@RequestBody User user) */ @Test public void testUpdateUser() throws Exception { User user = new User(); user.setId(2L); user.setUsername("tom"); String respone = mockMvc.perform( put(Urls.User.UPDATE_USER).contentType(MediaType.APPLICATION_JSON_UTF8).content(JSON.toJSONString(user))) .andDo(print()).andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); Assert.assertNotNull(respone); System.out.println(respone); }

4 .RequestBuilder/MockMvcRequestBuilders 相关API详细描述

RequestBuilder/MockMvcRequestBuilders

从名字可以看出,RequestBuilder用来构建请求的,其提供了一个方法buildRequest(ServletContext servletContext)用于构建MockHttpServletRequest;其主要有两个子类MockHttpServletRequestBuilder和MockMultipartHttpServletRequestBuilder(如文件上传使用),即用来Mock客户端请求需要的所有数据.

4.1 .MockMvcRequestBuilders主要API

MockHttpServletRequestBuilder get(String urlTemplate, Object… urlVariables):根据uri模板和uri变量值得到一个GET请求方式的MockHttpServletRequestBuilder;如get(/user/{id}, 1L);

  • MockHttpServletRequestBuilder post(String urlTemplate, Object… urlVariables):同get类似,但是是POST方法;
  • 提供自己的Http请求方法及uri模板和uri变量,如上API都是委托给这个API;
  • MockMultipartHttpServletRequestBuilder fileUpload(String urlTemplate, Object… urlVariables):提供文件上传方式的请求,得MockMultipartHttpServletRequestBuilder;
  • RequestBuilder asyncDispatch(final MvcResult mvcResult):创建一个从启动异步处理的请求的MvcResult进行异步分派的RequestBuilder;
  • MockHttpServletRequestBuilder和MockMultipartHttpServletRequestBuilder API
  • MockHttpServletRequestBuilder API
  • MockHttpServletRequestBuilder header(String name, Object… values)/MockHttpServletRequestBuilder headers(HttpHeaders httpHeaders):添加头信息;
  • MockHttpServletRequestBuilder contentType(MediaType mediaType):指定请求的contentType头信息;
  • MockHttpServletRequestBuilder accept(MediaType… mediaTypes)/MockHttpServletRequestBuilder accept(String… mediaTypes):指定请求的Accept头信息;
  • MockHttpServletRequestBuilder content(byte[] content)/MockHttpServletRequestBuilder content(String content):指定请求Body体内容;
  • MockHttpServletRequestBuilder cookie(Cookie… cookies):指定请求的Cookie;
  • MockHttpServletRequestBuilder locale(Locale locale):指定请求的Locale;
  • MockHttpServletRequestBuilder characterEncoding(String encoding):指定请求字符编码;
  • MockHttpServletRequestBuilder requestAttr(String name, Object value) :设置请求属性数据;
  • MockHttpServletRequestBuilder sessionAttr(String name, Object value)/
  • MockHttpServletRequestBuilder sessionAttrs(Map<\string, object=”“> \sessionAttributes):设置请求session属性数据;
  • MockHttpServletRequestBuilder flashAttr(String name, Object value)/MockHttpServletRequestBuilder flashAttrs(Map<\string, object=”“>\ flashAttributes):指定请求的flash信息,比如重定向后的属性信息;
  • MockHttpServletRequestBuilder session(MockHttpSession session) :指定请求的Session;
  • MockHttpServletRequestBuilder principal(Principal principal) :指定请求的Principal;
  • MockHttpServletRequestBuilder contextPath(String contextPath) :指定请求的上下文路径,必须以“/”开头,且不能以“/”结尾;
  • MockHttpServletRequestBuilder pathInfo(String pathInfo) :请求的路径信息,必须以“/”开头;
  • MockHttpServletRequestBuilder secure(boolean secure):请求是否使用安全通道;
  • MockHttpServletRequestBuilder with(RequestPostProcessor postProcessor):请求的后处理器,用于自定义一些请求处理的扩展点;

4.2 MockMultipartHttpServletRequestBuilder 主要API

  • MockMultipartHttpServletRequestBuilder file(String name, byte[] content)/MockMultipartHttpServletRequestBuilder file(MockMultipartFile file):指定要上传的文件;

4.3 ResultActions

调用MockMvc.perform(RequestBuilder requestBuilder)后将得到ResultActions,通过ResultActions完成如下三件事:

  • ResultActions andExpect(ResultMatcher matcher) :添加验证断言来判断执行请求后的结果是否是预期的;
  • ResultActions andDo(ResultHandler handler) :添加结果处理器,用于对验证成功后执行的动作,如输出下请求/结果信息用于调试;
  • MvcResult andReturn() :返回验证成功后的MvcResult;用于自定义验证/下一步的异步处理;
  • **ResultMatcher/MockMvcResultMatchers **

ResultMatcher用来匹配执行完请求后的结果验证,其就一个match(MvcResult result)断言方法,如果匹配失败将抛出相应的异常;spring mvc测试框架提供了很多***ResultMatchers来满足测试需求。注意这些***ResultMatchers并不是ResultMatcher的子类,而是返回ResultMatcher实例的。Spring mvc测试框架为了测试方便提供了MockMvcResultMatchers静态工厂方法方便操作;

具体的API如下:

  • 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)

发表评论

表情:
评论列表 (有 0 条评论,539人围观)

还没有评论,来说两句吧...

相关阅读