这种组合方式,依赖的是JUnit和Spring容器,进行对象注入,而Mockit的作用是在spring生成的bean中,注入mock对象。相当于使用了Mockito的一部分功能。
1、首先导入包:
<dependencies>
<!--spring的包忽略-->
...
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
</dependencies>
2、被测试类production-class:
@Service
public class MySomeServiceImpl implements SomeService {
@Resource
private ServiceA serviceA;
@Resource
private ServiceB serviceB;
@Value("${server.port}")
private int port;
public String sayHello(){
String result=null;
List<String> list=serviceA.getText("zhangsan",12);
// do...
result=list.get(0);
return result;
}
}
3、单元测试-配置项:
@ComponentScan(basePackages = "com.test.impl", excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = CommonService.class),
@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Value.class)
})
@Configuration
public class MySomeServiceImplConfgure {
@Bean
public ServiceA serviceA() {
ServiceA serviceA = Mockito.mock(ServiceA.class);
Mockito.when(serviceA.getText(Mockito.any(String.class))).thenReturn("AAA");
return serviceA;
}
@Bean
public ServiceB serviceB(){return null;}
}
4、单元测试-执行类:
@ContextConfiguration(classes = MySomeServiceImplConfgure.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class MySomeServiceImplTest {
@Resource
private MySomeService mySomeService;
@Test
public void sayHelloTest() {
String result=mySomeService.sayHello();
Assert.assertEquals("执行失败", pickZoneNos, "AAA");
}
}
5、总结
以上述方式执行单元测试,走的是JUnit4的框架流程。并且由于使用@Resource,实际是通过从spring容器中获取bean的方式得到的对象。而且是通过配置项当中@ComponentScan的方式找到的bean定义。
在这种实现方式中,Spring还提供一些非必需的bean,如serviceB。
而Mockito则是在执行sayHello()方法时,内部serviceA.getText()的调用时,创建了挡板。
这种方式有个问题,在遇到@Value方式读取配置信息port时,无法获取到,启动会抛异常,因此在ComponentSacn中排除@Value的字段。如果需要用到,则要通过@ImportSource(“classpath:appCtx.xml”)方式将*.properties加载进来。