1.使用场景
对模块进行集成测试时,希望能够通过输入URL对Controller进行测试,如果通过启动服务器,建立http client进行测试,这样会使得测试变得很麻烦,比如,启动速度慢,测试验证不方便,依赖网络环境等
MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便
2. 流程解析
- MockMvcBuilder实例化MockMvc
- mockMvc调用perform,执行一个RequestBuilder请求,调用controller的业务处理逻辑
- perform返回ResultActions,返回操作结果,通过ResultActions,提供了统一的验证方式
- 使用StatusResultMatchers对请求结果进行验证
- 使用ContentResultMatchers对请求返回的内容进行验证
3. 测试
3.1 controller
package com.tcp.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/tcp")
public class TcpController {
//测试Controller所用
@RequestMapping("/test")
public String test(){
return "success";
}
@RequestMapping("/mock")
public String testMockMvc(String s){
return "success" + s;
}
}
3.2 测试类
package com.tcp.controller;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
public class TcpControllerTest {
MockMvc mockMvc;
@Autowired
WebApplicationContext webApplicationContext;
@Before
public void setup(){
mockMvc = MockMvcBuilders.standaloneSetup(new TcpController()).build();
}
@Test
public void test() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/tcp/mock")
.accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
.param("s","jbp")
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(print()); //输出MvcResult到控制台
}
}
3.3 结果
4. 部分API解析
4.1 MockMvc的2种实例化方式
// 实例化方式一,通过参数指定一组控制器,这样就不需要从上下文获取了
mockMvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
// 实例化方式二,指定WebApplicationContext,将会从该上下文获取相应的控制器并得到相应的MockMvc
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
4.2 API解析
//mockMvc.perform 表示执行一个请求
mockMvc.perform(MockMvcRequestBuilders
.get("/xxx") //构造一个请求
// 设置返回值类型为utf-8,否则默认为ISO-8859-1
.accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
.param("xxx", "xxx"))//添加请求传值
//ResultActions.andExpect 添加执行完成后的断言,验证控制器执行完成后结果是否正确
.andExpect(MockMvcResultMatchers.status().isOk())//验证状态码是否正确
.andExpect(MockMvcResultMatchers.content().string("xxx"))//验证输出内容是否一致
.andDo(MockMvcResultHandlers.print());