Reputation: 115
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
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