通常,在我们平时开发项目时,如果想要输入URL对Controller进行测试,在代码编辑之后,需要重启服务器,建立http client进行测试。这样会使得测试变得很麻烦,比如,启动速度慢,测试验证不方便,依赖网络环境等,这样会导致测试无法进行,为了可以对Controller进行测试,可以通过引入MockMVC进行解决。
MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。
MockMvcBuilder是用来构造MockMvc的构造器,其主要有两个实现:StandaloneMockMvcBuilder和DefaultMockMvcBuilder,分别对应两种测试方式,即独立安装和集成Web环境测试(此种方式并不会集成真正的web环境,而是通过相应的Mock API进行模拟测试,无须启动服务器)。对于我们来说直接使用静态工厂MockMvcBuilders创建即可。
下面就写几个简单的案例,使用MockMvc测试Controller中的get请求和post请求。
1.引入jar包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
2.编写测试controller
/** * @author Sue * @create 2019-09-06 10:03 **/ @RestController @RequestMapping("/mock") public class MockmvcController { /** * get请求 * @param username * @param password * @return */ @GetMapping("/getInfo") public R getInfo(String username,String password){ System.out.println("username:" + username + "," + "password:" + password); return R.ok(); } /** * post请求 * @param username * @param password * @return */ @PostMapping("/getInfo2") public R getInfo2(String username,String password){ System.out.println("username:" + username + "," + "password:" + password); return R.ok(); } /** * post请求接收json格式 * @param user * @return */ @PostMapping("/getInfo3") public R getInfo3(@RequestBody User user){ System.out.println(user); return R.ok(user); } }
3.创建单元测试
idea使用快捷键ctrl+alt+t
@RunWith(SpringRunner.class) @SpringBootTest public class MockmvcTest { // 注入web环境的ApplicationContext容器 @Autowired private WebApplicationContext context; /** * 模拟mvc测试对象 */ private MockMvc mockMvc; /** * 所有测试方法执行之前执行该方法 */ @Before // 这个注解的作用,在每个方法之前都会执行一遍 public void before() throws Exception { //获取mockmvc对象实例 mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); } @Test public void getInfo() throws Exception { MvcResult mvcResult = mockMvc.perform( MockMvcRequestBuilders.get("/mock/getInfo") .param("username", "Jack") .param("password", "Jack001")) .andExpect(MockMvcResultMatchers.status().isOk()) .andDo(MockMvcResultHandlers.print()).andReturn(); System.out.println("输出 " + mvcResult.getResponse().getContentAsString()); } @Test public void getInfo2() throws Exception { MvcResult mvcResult = mockMvc.perform( MockMvcRequestBuilders.post("/mock/getInfo2") .accept(MediaType.APPLICATION_JSON) .param("username", "Jack") .param("password", "Jack001")) .andExpect(MockMvcResultMatchers.status().isOk()) .andDo(MockMvcResultHandlers.print()).andReturn(); System.out.println("输出 " + mvcResult.getResponse().getContentAsString()); } @Test public void getInfo3() throws Exception { User user = new User(); user.setUsername("Jack"); user.setPassword("Jack001"); String jsonString = JSON.toJSONString(user); MvcResult mvcResult = mockMvc.perform( MockMvcRequestBuilders.post("/mock/getInfo3") .contentType(MediaType.APPLICATION_JSON) .content(jsonString) .accept(MediaType.APPLICATION_JSON) ) .andExpect(MockMvcResultMatchers.status().isOk()) .andDo(MockMvcResultHandlers.print()).andReturn(); int status = mvcResult.getResponse().getStatus(); Assert.assertTrue("正确", status == 200); System.out.println("输出 " + mvcResult.getResponse().getContentAsString()); } }
4.测试
代码解析 :
perform
:执行一个RequestBuider
请求,自动执行SpringMvc
的流程并映射到相应的控制器执行处理get
: 声明一个发送get
请求的方法.public static MockHttpServletRequestBuilder get(String urlTemplate, Object... uriVars) { return new MockHttpServletRequestBuilder(HttpMethod.GET, urlTemplate, uriVars);}
这是个静态方法,可以直接导入,根据uri模版和uri的变量值得到一个get
请求的方法. 另外提供了其他的请求方法, 如:post
、put
、delete
等.andExperct
: 添加ResultMatcher
验证规则,验证perform
执行完成后的结果是否正确(对返回的数据进行判断)andDo
: 添加ResultHandler
结果处理器,比如调试打印结果到控制台print()
andReturn
: 最后返回相应的MvcResult
,然后进行自定义验证/进行下一步的异步处理.
整个测试过程如下:
1、准备测试环境
2、通过MockMvc执行请求
3、添加验证断言
4、添加结果处理器
5、得到MvcResult进行自定义断言/进行下一步的异步请求
6、卸载测试环境
通过这几个方法,相信大家对mockMvc测试有了一些了解,如果想要使用更多细节,通过方法名和参数应该也能看懂方法含义,如果还是不能理解,可以查看下面的官方文档配合使用。