springmvc之测试MockMvc
一.前言
在项目完成之后,在对项目模块进行测试时,一般的流程是启动服务,在测试工具上进行测试,比如postMan,这样会使得测试变得很麻烦,比如,启动速度慢,测试验证不方便,依赖网络环境等等问题,所以为了可以对Controller进行测试,我们引入了MockMVC。它实现了模拟web端对Http的请求,使得测试更加简洁方便、不依赖网络环境,而且提供了一套验证的工具。
二.测试流程
- MockMvcBuilder构造MockMvc的构造器MockMvcBuilder
- mockMvc调用perform,执行一个RequestBuilder请求,调用controller层的方法
- perform返回ResultActions,返回操作结果,通过ResultActions,提供了统一的验证方式
- 使用StatusResultMatchers对请求结果进行验证,如状态码
- 使用ContentResultMatchers对请求返回的内容进行验证
- 使用MockMvcResultHandlers对请求结果进行输出打印
三.MockMvc的API
(1)@RunWith注解
指定测试运行器,例如使用 SpringJUnit4ClassRunner.class
(2)@ContextConfiguration注解
执行要加载的配置文件,例如 classpath:application.xml 或 file:src/main/resources/DispatcherServlet-servlet.xml
(3)@WebAppConfiguration注解
用于声明测试时所加载的是WebApplicationContext【WebMVC的 XmlWebApplicationContext 是其实现类】
因为测试需要使用WebMVC对应的IOC容器对象
⑷ WebApplicationContext
WebMVC的IOC容器对象,需要声明并通过@Autowired自动装配进来
⑸ MockMvcRequestBuilders
用于构建MockHttpServletRequestBuilder
① get GET请求
② post POST请求
③ put PUT请求
④ delete DELETE请求
⑤ param(String name, String… values) 传递参数 K-V…
⑹ MockHttpServletRequestBuilder
用于构建 MockHttpServletRequest,它用于作为 MockMvc的请求对象
⑺ MockMvc
通过 MockMvcBuilders 的 webAppContextSetup(WebApplicationContext context) 方法 获取 DefaultMockMvcBuilder,再调用 build() 方法,初始化 MockMvc
① perform
perform(RequestBuilder requestBuilder) throws Exception
执行请求,需要传入 MockHttpServletRequest 对象【请求对象】
② andDo
andDo(ResultHandler handler) throws Exception
执行普通处理,例如 MockMvcResultHandlers的print() 方法用于 打印请求、响应及其他相关信息
③ andExpect
andExpect(ResultMatcher matcher) throws Exception
执行预期匹配,例如:
MockMvcResultMatchers.status().isOk() 预期响应成功
MockMvcResultMatchers.content().string(final String expectedContent) 指定预期的返回结果内容[字符串]
MockMvcResultMatchers.content().contentType(String contentType) 指定预期的返回结果的媒体类型
MockMvcResultMatchers.forwardedUrl(final String expectedUrl) 指定预期的请求的URL链接
MockMvcResultMathcers.redirectedUrl(final String expectedUrl) 指定预期的重定向的URL链接
注意:当有一项不满足时,则后续就不会进行。
④ andReturn
andReturn()
返回 MvcResult [请求访问结果]对象
⑤ getRequest
getRequest()
返回 MockHttpServletRequest [请求]对象
四.springboot项目测试
1.初始化
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class BaseTestNg extends AbstractTestNGSpringContextTests {
@Autowired
private WebApplicationContext wac;
public MockMvc mockMvc;
@BeforeClass
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
}
2.get请求测试
controller层方法
@GetMapping("/hello")
public String hello(int a){
System.out.println("hello =>");
return "hello world:"+a;
}
测试用例
@Test(dataProvider = "num")
public void testUser(int a) throws Exception {
MvcResult result = mockMvc.perform(get("/hello")
.param("a",a+""))
.andDo(MockMvcResultHandlers.print())
.andReturn();
Assert.assertNotNull(result);
}
@DataProvider(name = "num")
public Object[][] provideData() {
return new Object[][] { { 1}, { 2}, { 4} };
}
测试结果
3.post测试
controller层方法
@PostMapping("/login")
public String login(User user){
System.out.println("用户:"+user.toString());
return "结果:"+"用户名"+user.getUsername()+" 密码"+user.getPassword();
}
测试用例
@Test(dataProvider = "users")
public void testLogin(User user) throws Exception {
mockMvc.perform(post("/login")
.contentType(MediaType.APPLICATION_FORM_URLENCODED) //数据的格式
.param("username", user.getUsername()).param("password", user.getPassword()))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
}
@DataProvider(name = "users")
public Object[][] userList() {
return new Object[][] { { new User("1","1")},
{ new User("2","2")},
{ new User("3","3")} };
}
测试