1, Foreword
1. Problems encountered:
In order to ensure the stable online operation of the function, coverage unit test must be carried out before the function is online, but the integration test can only be carried out because the interface test needs to be called through PostMan or Swagger. Moreover, after testing through PostMan or Swagger, the test cases cannot be saved, so it is impossible to ensure whether the test cases are fully covered, and the test cases cannot be saved.
2. Solution:
The interface call unit test is performed by injecting Mock into SpringBootTest.
2, Function code
@RestController("/user") public class UserController { @Autowired private UserService userService; @GetMapping("/list") public ResponseEntity<List<User>> list() { return new ResponseEntity(list, HttpStatus.OK); } /** * user Filter conditions stored in */ @PostMapping("/list2") public ResponseEntity<List<User>> list(User user, @RequestParam(name = "current", defaultValue = "1") Integer current, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { return new ResponseEntity(list, HttpStatus.OK); } @PostMapping("/add") public ResponseEntity<String> add(@RequestBody User user){ userService.add(user); return new ResponseEntity("success", HttpStatus.OK); } }
3, Integrated Mock
1. Import test dependencies for SpringBoot
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency>
2. Create a test case
(1) @ RunWith and @ SpringBootTest: represent a test class that can start the container.
(2) @ WebAppConfiguration: indicates that the ApplicationContext used by the test environment will be of WebApplicationContext type.
(3) @ AutoConfigureMockMvc: indicates that it is a class that can conduct unit testing through Mock.
@RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) @WebAppConfiguration // @AutoConfigureMockMvc is used to automatically configure MockMvc @AutoConfigureMockMvc public class UserController01Test { @Autowired private WebApplicationContext webApplicationContext; @Autowired private MockMvc mockMvc; @Before() public void setup () { mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext).build(); } @Test public void test () { // test method can write interface call logic specifically, which is mainly to fill in the analog interface input parameter call. } @Test public void demo () { // Add the interface path of the call MockHttpServletRequestBuilder postRequestBuilder = MockMvcRequestBuilders.post("/user/add"); // Identify data submission method postRequestBuilder.contentType(MediaType.APPLICATION_JSON); // parameter postRequestBuilder.param("name", "Zhang San"); postRequestBuilder.param("age", "18"); // mock call ResultActions resultActions = mockMvc.perform(postRequestBuilder); // Execute what is expected to be executed after the call is successful resultActions.andExpect(MockMvcResultMatchers.status().isOk()); // Perform general operations and output call results resultActions.andDo(MockMvcResultHandlers.print()); // Get the returned result information MvcResult response = resultActions.andReturn(); System.out.println("result:"+response.getResponse().getContentAsString()); } }
4, In depth analysis
1,MockMvcRequestBuilders
(1) MockHttpServletRequestBuilder supports all http requests (get, post, head, put, delete, etc.)
(2) When calling, you need to specify the request method (general scenarios, i.e. get and post) and interface path (e.g.: / demo/test), and then obtain the MockHttpServletRequestBuilder.
2. Assembly process of MockHttpServletRequestBuilder
(1) headers() method: add header information.
(2) contentType() method: specify the contentType header information of the request.
(3) content() method: specify the Body content of the request. (both direct and String strings can be supported)
(4) param()/params() method: set the interface parameter value.
⚠️ be careful ⚠️: It mainly describes the core methods currently used, and others are not described in detail here. Cookies and session s can also be simulated. If necessary, you can see Kaitao's blog article in the reference, which explains the use method in detail.
3. Calling procedure of MockMvc
(1) perform() method: execute a RequestBuilder request, which will automatically execute the spring MVC process and map it to the corresponding controller for processing.
(2) andExpect() method: add a ResultMatcher verification rule to verify whether the result is correct after the controller is executed. Add validation assertions to determine whether the result after executing the request is expected.
(3) andDo() method: add ResultHandler result processor to perform actions after successful verification, such as printing results to the console during debugging.
(4) andReturn() method: returns the corresponding MvcResult; Then perform custom verification / asynchronous processing in the next step.
5, Request example
1. Get request- No parameters
(1) Code example
public void testGet () throws Exception { MockHttpServletRequestBuilder postRequestBuilder = MockMvcRequestBuilders .get("/user/list") .contentType(MediaType.APPLICATION_JSON); MvcResult response = mockMvc.perform(postRequestBuilder) .andExpect(MockMvcResultMatchers.status().isOk()) .andDo(MockMvcResultHandlers.print()) .andReturn(); System.out.println("result:"+response.getResponse().getContentAsString()); }
(2) Request body
(3) Response return result
2. Get request- With parameters
(1) Code example
public void testGet () throws Exception { MockHttpServletRequestBuilder postRequestBuilder = MockMvcRequestBuilders .get("/user/list") .contentType(MediaType.APPLICATION_JSON) .param("biz_date", "2021-11-05") .param("operator_name", "Zhang San"); MvcResult response = mockMvc.perform(postRequestBuilder) .andExpect(MockMvcResultMatchers.status().isOk()) .andDo(MockMvcResultHandlers.print()) .andReturn(); System.out.println("result:"+response.getResponse().getContentAsString()); }
(2) Request body
(3) Response return result
3. Post request - Paramter form
(1) Code example
public void testPost () throws Exception { MockHttpServletRequestBuilder postRequestBuilder = MockMvcRequestBuilders .post("/user/add") .contentType(MediaType.APPLICATION_JSON) .param("name", "Zhang San") .param("age", "18"); MvcResult response = mockMvc.perform(postRequestBuilder) .andExpect(MockMvcResultMatchers.status().isOk()) .andDo(MockMvcResultHandlers.print()) .andReturn(); System.out.println("result:"+response.getResponse().getContentAsString()); }
(2) Request body
(3) Response return result
4. Post request - RequestBody content form
(1) Code example
public void testPost () throws Exception { Map<String, String> paramMap = new HashMap<>(); paramMap.put("name", "Zhang San"); paramMap.put("age", "18"); MockHttpServletRequestBuilder postRequestBuilder = MockMvcRequestBuilders .post("/user/add") .contentType(MediaType.APPLICATION_JSON) .content(JSON.toJSON(paramMap).toString()); MvcResult response = mockMvc.perform(postRequestBuilder) .andExpect(MockMvcResultMatchers.status().isOk()) .andDo(MockMvcResultHandlers.print()) .andReturn(); System.out.println("result:"+response.getResponse().getContentAsString()); }
(2) Request body
(3) Response return result
The above is the overall process of interface unit test for SpringBoot integrated Mock. If you have any questions, please communicate with me in time. Thank you!!!
reference material
Spring official website test case
Detailed explanation of Spring MVC testing framework -- server side testing