@InjectMocks与@Mock测试RequestListServiceImpl报错及必要性咨询
问题根源
你混淆了两个Mockito注解的作用:
@Mock是创建完全模拟的假对象,所有方法都是空实现,默认返回null,必须手动打桩才能指定返回值@InjectMocks是创建真实的目标类对象,会自动把你声明的@Mock对象注入到它的依赖里,目的就是测试真实业务逻辑
第二个测试报错的核心原因是:你完全不该验证被测试类本身的方法调用,verify方法只能作用于mock对象,你要验证的是service依赖的dao层方法有没有被正确调用。
正确解决方案
第一步:保留@InjectMocks注解
不要把RequestListServiceImpl的注解改成@Mock,你要测试service的真实业务逻辑,就必须用真实的service对象,用@Mock的话你测的都是自己打桩的假逻辑,没有任何测试价值。
第二步:修改testCreateRequest的验证逻辑
把验证service本身的代码删掉,改成验证dao层方法的调用,修改后代码如下:
@Test public void testCreateRequest() throws Exception { // 打桩dao层的getTime方法 when(requestListDao.getTime(anyString())).thenReturn(0); RequestList r = new RequestList(); r.setCreateName("demo"); // 调用被测试类的真实方法 requestListServiceImpl.createRequest(r); // 验证dao层的方法被正确调用 // 验证getTime方法被调用1次,参数为demo verify(requestListDao, times(1)).getTime("demo"); // 捕获传入dao的参数,验证time字段被正确+1 ArgumentCaptor<RequestList> requestCaptor = ArgumentCaptor.forClass(RequestList.class); verify(requestListDao, times(1)).createRequest(requestCaptor.capture()); Assert.assertEquals(Integer.valueOf(1), requestCaptor.getValue().getTime()); }
常见疑问
@InjectMocks是必须的吗?
不是必须的,你也可以手动new RequestListServiceImpl(),再手动把mock出来的requestListDao通过构造方法或者set方法注入进去,效果和@InjectMocks完全一致,@InjectMocks只是用来简化注入代码的语法糖而已。
内容的提问来源于stack exchange,提问作者Junhong
相关产品推荐
相关产品推荐

