Mockito测试控制器
问题描述:
这是我第一次尝试Mockito。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
。
我在这里错过了什么?
答
当你嘲笑Mockito的东西时,它会嘲笑的一切返回某种默认值。对于对象,这是null
。对于整数/双打/等,这是0
,布尔值,false
。请参阅Mockito Docs。所以你不能进入它,因为它不是你的班级出现在被测试的控制器中,它是一个生成的代理,只是假装成你的班级(因此,嘲笑)。
如果你想改变你的类的行为,你将需要使用Mockito来告诉它返回不同的变量,这取决于传递给方法的内容或者它运行的是哪个测试。
when(patientManagementService.startVisit(1)).thenReturn(true);
将意味着,如果使用的是嘲笑PatientManagementService
电话patientManagementService.startVisit(patientBO.getId())
其中patientBO.getId()
回报1
,那么它将返回true任何代码,否则将返回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
。你将无法进入PatientRepository
,因为这将被嘲笑。
你究竟在这里如何使用Mockito?我看不出任何嘲笑,所以目前还不清楚为什么你用Mockito标记了这个。 – ipsi
对不起,我应该发布更完整的代码。请看更新的问题。谢谢! – abiieez