Mockito测试控制器

时间:2016-07-03 20:24:59

标签: spring-mvc 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

我在这里缺少什么?

1 个答案:

答案 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,因为那将被嘲笑。