Reputation: 3189
This is my first attempt with Mockito.
My controller
@RequestMapping(value = "/add", method = RequestMethod.POST)
@ResponseBody
public ValidationResponse startVisitForPatient(PatientBO patientBO,Locale locale) {
ValidationResponse res = new ValidationResponse();
if (patientManagementService.startVisit(patientBO.getId())){
res.setStatus(MessageStatus.SUCCESS);
res.setValue(messageSource.getMessage("success.message", null, locale));
}
else{
res.setValue(messageSource.getMessage("failed.message", null, locale));
res.setStatus(MessageStatus.FAILED);
}
return res;
}
The service
@Transactional
public boolean startVisit(long id) {
Patient patient = patientRepository.findOne(id);
Set<Encounter> encounters = patient.getEncounters();
Encounter lastEncounter = null;
Timestamp startVisitDate = null;
Timestamp endVisitDate = null;
if (encounters.iterator().hasNext()){
lastEncounter = encounters.iterator().next();
startVisitDate = lastEncounter.getStartVisitDate();
endVisitDate = lastEncounter.getEndVisitDate();
}
if (lastEncounter == null || (endVisitDate != null && endVisitDate.after(startVisitDate))){
Encounter newEncounter = new Encounter();
newEncounter.setCreatedBy(userService.getLoggedUserName());
newEncounter.setCreatedDate(new Timestamp(new Date().getTime()));
newEncounter.setModifiedBy(userService.getLoggedUserName());
newEncounter.setModifiedDate(newEncounter.getCreatedDate());
newEncounter.setPatient(patient);
newEncounter.setStartVisitDate(newEncounter.getCreatedDate());
encounters.add(newEncounter);
return true;
}
else
return false;
}
Unit test
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "file:src/main/webapp/WEB-INF/root-context.xml",
"file:src/main/webapp/WEB-INF/applicationContext.xml",
"file:src/main/webapp/WEB-INF/securityContext.xml" })
@WebAppConfiguration
public class Testing {
@InjectMocks
StaffVisitManagementController staffVisitManagementController;
@Mock
PatientManagementService patientManagementService;
@Mock
View mockView;
MockMvc mockMvc;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(staffVisitManagementController)
.setSingleView(mockView)
.build();
}
@Test
public void testStartVisit() throws Exception {
mockMvc.perform(post("/staff/visit/add").param("id", "1"))
.andExpect(status().isOk()).andExpect(content().string("success"));
}
}
The test method indeed calls the controller. However I am not able to debug the service at this line
patientManagementService.startVisit(patientBO.getId()))
All it returns is just false
.
What am I missing here ?
Upvotes: 0
Views: 2340
Reputation: 2070
When you mock something with Mockito, it mocks out everything to return some sort of default. For objects, this is null
. For integers/doubles/etc, this is 0
, for booleans, false
. See the Mockito Docs. So you can't step into it because it's not your class that's present in the controller under test, it's a generated proxy that is merely pretending to be your class (hence, mocking).
If you want to change the behaviour of your class, you will need to use Mockito to tell it to return different variables depending on what is passed to the method, or which test it's running in. e.g.
when(patientManagementService.startVisit(1)).thenReturn(true);
Would mean that, if any code using the mocked PatientManagementService
calls patientManagementService.startVisit(patientBO.getId())
where patientBO.getId()
returns 1
, then it will return true, otherwise it will return false
, which is the default answer.
In your case, I suspect you would be better off mocking out patientRepository
, rather than patientManagementService
if you want to be able to step into your service-layer code.
EDIT:
Roughly what I would suggest is:
private StaffVisitManagementController staffVisitManagementController;
private PatientManagementService patientManagementService;
@Mock
private PatientRepository patientRepository;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
when(patientRepository.findOne(1)).thenReturn(new Patient());
patientManagementService = new PatientManagementService(patientRepository);
staffVisitManagementController = new StaffVisitManagementController(patientManagementService);
mockMvc = MockMvcBuilders.standaloneSetup(staffVisitManagementController)
.setSingleView(mockView)
.build();
}
Obviously, the name of repository class may be different, and you may be using field inject instead of constructor injection, etc, etc, but otherwise this should allow you to step into the PatientManagementService
with the debugger. You will not be able to step into the PatientRepository
, as that will be mocked.
Upvotes: 2