MockMVC类是Spring MVC测试框架的一部分,它通过启动一个Servlet容器帮助测试REST控制器。
在这个MockMVC教程中,我们将使用它和Spring boot的WebMvcTest类来执行Junit测试用例,该测试用例测试为Spring boot 2 hateoas编写的REST控制器方法。
Maven依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency>
|
一个JUnit测试类来测试Spring MVC控制器请求和响应,我们可以使用下面给出的配置。
@RunWith(SpringRunner.class) @WebMvcTest(EmployeeRESTController.class) public class TestEmployeeRESTController { @Autowired private MockMvc mvc; }
|
- SpringRunner是SpringJUnit4ClassRunner别名。它是JUnit的BlockJUnit4ClassRunner的自定义扩展,它通过TestContextManager和相关的支持类和注释为标准JUnit测试提供Spring TestContext Framework的功能。
- @WebMvcTest注释用于Spring MVC测试。它禁用完全自动配置,而只应用与MVC测试相关的配置。
- WebMvcTest注释将自动配置MockMvc实例。
- 使用EmployeeRESTController.classas参数,我们要求只初始化一个Web控制器,您需要使用Mock对象提供所需的剩余依赖项。
HTTP GET
假设有一个Rest控制器:
@GetMapping(value = "/employees") public EmployeeListVO getAllEmployees() { //code } @GetMapping(value = "/employees/{id}") public ResponseEntity<EmployeeVO> getEmployeeById (@PathVariable("id") int id) { //code }
|
下面给出了相应的方法测试:
@Autowired private MockMvc mvc; @Test public void getAllEmployeesAPI() throws Exception { mvc.perform( MockMvcRequestBuilders .get("/employees") .accept(MediaType.APPLICATION_JSON)) .andDo(print()) .andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$.employees").exists()) .andExpect(MockMvcResultMatchers.jsonPath("$.employees<li>.employeeId").isNotEmpty()); } @Test public void getEmployeeByIdAPI() throws Exception { mvc.perform( MockMvcRequestBuilders .get("/employees/{id}", 1) .accept(MediaType.APPLICATION_JSON)) .andDo(print()) .andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$.employeeId").value(1)); }
|
HTTP POST
案例:
@PostMapping(value = "/employees") public ResponseEntity<EmployeeVO> addEmployee (@Valid @RequestBody EmployeeVO employee) { //code return new ResponseEntity<EmployeeVO>(employee, HttpStatus.CREATED); }
|
对于post json请求的相应spring springmvc测试如下:
@Autowired private MockMvc mvc; @Test public void createEmployeeAPI() throws Exception { mvc.perform( MockMvcRequestBuilders .post("/employees") .content(asJsonString(new EmployeeVO(null, "firstName4", "lastName4", "email4@mail.com"))) .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) .andExpect(MockMvcResultMatchers.jsonPath("$.employeeId").exists()); } public static String asJsonString(final Object obj) { try { return new ObjectMapper().writeValueAsString(obj); } catch (Exception e) { throw new RuntimeException(e); } }
|
HTTP PUT
HTTP API在控制器中定义为:
@PutMapping(value = "/employees/{id}") public ResponseEntity<EmployeeVO> updateEmployee (@PathVariable("id") int id, @Valid @RequestBody EmployeeVO employee) { //code return new ResponseEntity<EmployeeVO>(emp, HttpStatus.OK); }
|
相应的方法测试是
@Test public void updateEmployeeAPI() throws Exception { mvc.perform( MockMvcRequestBuilders .put("/employees/{id}", 2) .content(asJsonString(new EmployeeVO(2, "firstName2", "lastName2", "email2@mail.com"))) .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$.firstName").value("firstName2")) .andExpect(MockMvcResultMatchers.jsonPath("$.lastName").value("lastName2")) .andExpect(MockMvcResultMatchers.jsonPath("$.email").value("email2@mail.com")); }
|
HTTP DELETE:
@DeleteMapping(value = "/employees/{id}") public ResponseEntity<HttpStatus> removeEmployee (@PathVariable("id") int id) { //code return new ResponseEntity<HttpStatus>(HttpStatus.ACCEPTED); }
|
相应的方法测试是:
@Test public void deleteEmployeeAPI() throws Exception { mvc.perform( MockMvcRequestBuilders.delete("/employees/{id}", 1) ) .andExpect(status().isAccepted()); }
|