Issue
I'm trying to make an integration test going all the way from the top (controller) down to the repositories (mocked). I'm having issue with getting an actual service (not mock) injected into a controller and mocking the service's repositories. Most examples I've seen either call the endpoint via MockMvc and test the controller that contains all the logic, so no services, or they just mock the service and return a set response which I see no point in testing at all. My classes work as such: Controller contains the service which contains the repository
Currently I have the following test class for that:
@WebMvcTest(PatientRecordController.class)
public class PatientRecordControllerTests {
@Autowired
MockMvc mockMvc;
@Autowired
ObjectMapper mapper;
@MockBean
PatientRecordService patientRecordService;
@Test
public void createRecord_WhenDtoValid_CreateRecord() throws Exception {
PatientRecordDto recordDto = PatientRecordDto.builder()
.name("John Doe")
.age(47)
.address("New York USA")
.build();
PatientRecord record = ModelMapperUtil.convertTo(recordDto, PatientRecord.class);
Mockito.when(patientRecordService.saveRecord(recordDto)).thenReturn(record);
MockHttpServletRequestBuilder mockRequest = MockMvcRequestBuilders.post("/patient")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(this.mapper.writeValueAsString(recordDto));
mockMvc.perform(mockRequest)
.andExpect(status().isOk())
.andExpect(jsonPath("$", notNullValue()))
.andExpect(jsonPath("$.name", is("John Doe")));
}
}
What I would like to be able to do is something akin to following:
@Autowired
@InjectMocks
private PatientRecordService patientRecordService;
@Mock
private PatientRecordRepository patientRecordRepository;
Theoretically, with this I'd get a bean of PatientRecordService
that has PatientRecordRepository
mock injected, and then instead of doing
Mockito.when(patientRecordService.saveRecord(recordDto)).thenReturn(record);
I could do
Mockito.when(patientRecordRepository.save(recordDto)).thenReturn(record);
And then the whole logic inside of the service would be tested and only repository response would be mocked. Obviously this is not how it works, so how would I go about in achieving this?
Solution
You should be able to
@WebMvcTest({PatientRecordController.class, PatientRecordService.class})
@MockBean
private PatientRecordRepository patientRecordRepository;
Does that not achieve what you need?
Answered By - Erwin
Answer Checked By - Mary Flores (JavaFixing Volunteer)