2016-07-03 167 views
0

这是我第一次尝试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

我在这里错过了什么?

+0

你究竟在这里如何使用Mockito?我看不出任何嘲笑,所以目前还不清楚为什么你用Mockito标记了这个。 – ipsi

+0

对不起,我应该发布更完整的代码。请看更新的问题。谢谢! – abiieez

回答

2

当你嘲笑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,因为这将被嘲笑。

+0

感谢您的信息。你能用我的代码来说明吗? – abiieez

+0

看看编辑,我强烈建议通过Mockito文档 - 它有很多功能,比我可以合理地涵盖在这个答案。 – ipsi

+0

当然,你的回答非常有帮助。谢谢 ! – abiieez