Diluted Dev
Diluted Dev

Reputation: 115

Unable to get response body in mockMVC

I am trying to write test cases for controller layer in Spring boot using mockMVC, the test case passes but I am unable to see anything in the response body section.

The controller function:

private IPatientService patientService;

public PatientController(IPatientService patientService){
    this.patientService = patientService;
}

@PostMapping (value = "/save")
public ResponseEntity<Patient> savePatient(@RequestBody Patient patient) {
    return ResponseEntity.ok().body(patientService.savePatient(patient));
}

The test case :

@Autowired
MockMvc mockMvc;

@Mock
IPatientService iPatientService;

@InjectMocks
PatientController patientController;

Patient patient = new Patient();

@BeforeEach
void setUp() {
    mockMvc = MockMvcBuilders.standaloneSetup(patientController).build();
    patient.setId(1L);
}
@Test
@Order(1)
void savePatient() throws Exception {
    when(iPatientService.savePatient(patient)).thenReturn(patient);
    // The commented lines have been written for testing purposes and all of the following are working
    // ResponseEntity<Patient> response = patientController.savePatient(patient);
    // assertEquals(HttpStatus.OK, response.getStatusCode());
    // assertEquals(patient.getId(), response.getBody().getId());
    // System.out.println(response.getBody()); // response body contains the patient

    ObjectMapper mapper = new ObjectMapper();
    String jsonBody = mapper.writeValueAsString(patient);
    System.out.println(iPatientService.savePatient(patient).toString()); // prints json body containing the patient

    this.mockMvc.perform(post("/patient/save").content(jsonBody).contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andDo(print()); // Do print is not printing the patient in response body
}

The response contains nothing in the body

    MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = []
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Need some help with what's going on and how to proceed? I am not sure why there is nothing inside the body of response.

Upvotes: 0

Views: 3844

Answers (1)

M. Deinum
M. Deinum

Reputation: 124441

This is probably due to not implementing a correct equals and hashCode in your entities and in this case the Patient. How to implement a those methods properly can be found here.

In short add this to your Patient class.

@Entity
public Patient {

  public int hashCode() {
    return getClass().hashCode();
  }

  public boolean equals(Object obj) {
    if (this == obj) return true;
 
    if (if ( o == null || getClass() != o.getClass() ) {
            return false;
    }
    Patient other = (Patient) obj;
 
    return id != null &&
               id.equals(other.getId());
  }
}

With this your mocking, when(iPatientService.savePatient(patient)).thenReturn(patient);, will now match the patient.

Bonus tip use @WebMvcTest and @MockBean instead of what you are doing now.

@WebMvcTest(PatientController.class)
public class PatientControllerTests {
@Autowired
MockMvc mockMvc;

@MockBean
IPatientService iPatientService;

@Autowired
PatientController patientController;

Patient patient = new Patient();

@BeforeEach
void setUp() {
    patient.setId(1L);
}

@Test
@Order(1)
void savePatient() throws Exception {
    when(iPatientService.savePatient(patient)).thenReturn(patient);
patient

    ObjectMapper mapper = new ObjectMapper();
    String jsonBody = mapper.writeValueAsString(patient);
 
 
 
 this.mockMvc.perform(post("/patient/save").content(jsonBody).contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andDo(print());
}
}

Upvotes: 1

Related Questions