Home > database >  JUnit RestControllerTest for @PutMapping MockHttpServletResponse body is null
JUnit RestControllerTest for @PutMapping MockHttpServletResponse body is null

Time:05-04

I am stuck at a Controller Unit Test put method which always return an empty body response.

Below is my code:

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 which has @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("[email protected]")
            .build();

    Employee updatedEmployee = Employee.builder()
            .id(employeeId)
            .firstName("Jayyy")
            .lastName("Laiii")
            .email("[email protected]")
            .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())));
}

this is the output.

I do not really understand what I missed and any help would be appreciated, Thanks.

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":"[email protected]"}
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"**

CodePudding user response:

The problem is here

BDDMockito.given(employeeService.updateEmployee(employeeId, updatedEmployee))

Because your PUT request body through Controller is a JSON, not a Employee. In other words, the updatedEmployee you specified in test class doesn't match the employee in EmployeeServiceImpl, so the given...when... statement dosen't work as you expected. As a result, you got a empty response body.

You should modify your given...when... statement to

BDDMockito.given(employeeService.updateEmployee(eq(employeeId), any()))

then it will work correctly.

  • Related