@PutMapping MockHttpServletResponse 主体的 JUnit RestControllerTest 为空
JUnit RestControllerTest for @PutMapping MockHttpServletResponse body is null
我卡在控制器单元测试 put 方法中,该方法总是 return 空主体响应。
下面是我的代码:
EmployeeServiceImpl.class
@Override
public Employee updateEmployee(Long id, Employee employee) {
Employee existingEmployee = employeeRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("employee with id: " + id + " does not exist."));
existingEmployee.setFirstName(employee.getFirstName());
existingEmployee.setLastName(employee.getLastName());
existingEmployee.setEmail(employee.getEmail());
return employeeRepository.save(existingEmployee);
}
EmployeeController.class 有 @RequestMapping("/api/employees")
@PutMapping("/{id}")
public ResponseEntity<Employee> updateEmployee(@PathVariable Long id, @RequestBody Employee employee) {
return new ResponseEntity<>(employeeService.updateEmployee(id, employee), HttpStatus.OK);
}
EmployeeControllerTest.class
@Test
public void givenUpdatedEmployee_whenUpdateEmployee_thenReturnUpdatedEmployee() throws Exception {
Long employeeId = 1L;
Employee savedEmployee = Employee.builder()
.id(employeeId)
.firstName("Jay")
.lastName("Lai")
.email("jay@gmail.com")
.build();
Employee updatedEmployee = Employee.builder()
.id(employeeId)
.firstName("Jayyy")
.lastName("Laiii")
.email("jayyy@gmail.com")
.build();
BDDMockito.given(employeeService.getEmployeeBYId(employeeId))
.willReturn(savedEmployee);
BDDMockito.given(employeeService.updateEmployee(employeeId, updatedEmployee))
.willReturn(updatedEmployee);
ResultActions response = mockMvc.perform(MockMvcRequestBuilders.put("/api/employees/{id}", employeeId)
.contentType(MediaType.APPLICATION_JSON)
.content(mapper.writeValueAsString(updatedEmployee)));
response.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.jsonPath("$.firstName", CoreMatchers.is(updatedEmployee.getFirstName())))
.andExpect(MockMvcResultMatchers.jsonPath("$.lastName", CoreMatchers.is(updatedEmployee.getLastName())))
.andExpect(MockMvcResultMatchers.jsonPath("$.email", CoreMatchers.is(updatedEmployee.getEmail())));
}
这是输出。
我不太明白我错过了什么,如果有任何帮助,我们将不胜感激,谢谢。
MockHttpServletRequest:
HTTP Method = PUT
Request URI = /api/employees/1
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8", Content-Length:"73"]
Body = {"id":1,"firstName":"Jayyy","lastName":"Laiii","email":"jayyy@gmail.com"}
Session Attrs = {}
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
**java.lang.AssertionError: No value at JSON path "$.firstName"**
问题就在这里
BDDMockito.given(employeeService.updateEmployee(employeeId, updatedEmployee))
因为您通过 Controller 的 PUT 请求正文是 JSON
,而不是 Employee
。
换句话说,您在测试 class 中指定的 updatedEmployee
与 employee
不匹配
在 EmployeeServiceImpl
中,因此 given...when...
语句没有像您预期的那样工作。结果,您得到了一个空的响应正文。
您应该将 given...when...
语句修改为
BDDMockito.given(employeeService.updateEmployee(eq(employeeId), any()))
那么它将正常工作。
我卡在控制器单元测试 put 方法中,该方法总是 return 空主体响应。
下面是我的代码:
EmployeeServiceImpl.class
@Override
public Employee updateEmployee(Long id, Employee employee) {
Employee existingEmployee = employeeRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("employee with id: " + id + " does not exist."));
existingEmployee.setFirstName(employee.getFirstName());
existingEmployee.setLastName(employee.getLastName());
existingEmployee.setEmail(employee.getEmail());
return employeeRepository.save(existingEmployee);
}
EmployeeController.class 有 @RequestMapping("/api/employees")
@PutMapping("/{id}")
public ResponseEntity<Employee> updateEmployee(@PathVariable Long id, @RequestBody Employee employee) {
return new ResponseEntity<>(employeeService.updateEmployee(id, employee), HttpStatus.OK);
}
EmployeeControllerTest.class
@Test
public void givenUpdatedEmployee_whenUpdateEmployee_thenReturnUpdatedEmployee() throws Exception {
Long employeeId = 1L;
Employee savedEmployee = Employee.builder()
.id(employeeId)
.firstName("Jay")
.lastName("Lai")
.email("jay@gmail.com")
.build();
Employee updatedEmployee = Employee.builder()
.id(employeeId)
.firstName("Jayyy")
.lastName("Laiii")
.email("jayyy@gmail.com")
.build();
BDDMockito.given(employeeService.getEmployeeBYId(employeeId))
.willReturn(savedEmployee);
BDDMockito.given(employeeService.updateEmployee(employeeId, updatedEmployee))
.willReturn(updatedEmployee);
ResultActions response = mockMvc.perform(MockMvcRequestBuilders.put("/api/employees/{id}", employeeId)
.contentType(MediaType.APPLICATION_JSON)
.content(mapper.writeValueAsString(updatedEmployee)));
response.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.jsonPath("$.firstName", CoreMatchers.is(updatedEmployee.getFirstName())))
.andExpect(MockMvcResultMatchers.jsonPath("$.lastName", CoreMatchers.is(updatedEmployee.getLastName())))
.andExpect(MockMvcResultMatchers.jsonPath("$.email", CoreMatchers.is(updatedEmployee.getEmail())));
}
这是输出。
我不太明白我错过了什么,如果有任何帮助,我们将不胜感激,谢谢。
MockHttpServletRequest:
HTTP Method = PUT
Request URI = /api/employees/1
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8", Content-Length:"73"]
Body = {"id":1,"firstName":"Jayyy","lastName":"Laiii","email":"jayyy@gmail.com"}
Session Attrs = {}
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
**java.lang.AssertionError: No value at JSON path "$.firstName"**
问题就在这里
BDDMockito.given(employeeService.updateEmployee(employeeId, updatedEmployee))
因为您通过 Controller 的 PUT 请求正文是 JSON
,而不是 Employee
。
换句话说,您在测试 class 中指定的 updatedEmployee
与 employee
不匹配
在 EmployeeServiceImpl
中,因此 given...when...
语句没有像您预期的那样工作。结果,您得到了一个空的响应正文。
您应该将 given...when...
语句修改为
BDDMockito.given(employeeService.updateEmployee(eq(employeeId), any()))
那么它将正常工作。