这是我与Mockito的第一次尝试。
我的控制器
@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;
}
服务
@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;
}
单元测试
@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"));
}
}
测试方法确实调用了控制器。但是我无法在此行调试服务
patientManagementService.startVisit(patientBO.getId()))
它返回的只是false
。
我在这里缺少什么?
答案 0 :(得分:2)
当您使用Mockito模拟某些内容时,它会模拟所有内容以返回某种默认值。对于对象,这是null
。对于整数/双精度/等,对于布尔值0
,这是false
。请参阅Mockito Docs。所以你不能介入它,因为它不是你的类存在于被测控制器中,它是一个生成的代理,只是冒充你的类(因此,模拟)。
如果你想改变你的类的行为,你将需要使用Mockito告诉它返回不同的变量,具体取决于传递给方法的内容,或者运行的测试。例如
when(patientManagementService.startVisit(1)).thenReturn(true);
这意味着,如果使用模拟的PatientManagementService
调用patientManagementService.startVisit(patientBO.getId())
的任何代码patientBO.getId()
返回1
,那么它将返回true,否则它将返回{{1这是默认答案。
在您的情况下,如果您希望能够进入服务层代码,我怀疑您最好嘲笑false
,而不是patientRepository
。
编辑:
我的建议大致是:
patientManagementService
显然,存储库类的名称可能不同,您可能正在使用字段注入而不是构造函数注入等,但是否则这应该允许您使用调试器进入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();
}
。你将无法进入PatientManagementService
,因为那将被嘲笑。