转载:http://www.blogjava.net/qileilove/archive/2014/03/07/410713.html
1.关键词
  单元测试、spring、mockito
  2.概述
  单元测试目前已经成为项目中保证代码质量的一种必要方法,对于一些不易构造或者不易获取的对象通过mock的方式进行测试是一种很有效的处理办法。在基于spring的mock测试中,mock对象获取和使用的便利性可以提升单元测试代码的质量。
  3.实现原理
  Mock对象的注入使用注解和反射,对象注入依赖spring框架支持junit4提供的TestExcutionListeners监听器对象,在监听器中将mock对象注入到单元测试类中。
  4.新建对象方式代码
private IAccessServiceaccessService = Mockito.mock(IAccessService.class);
@BeforeClass
public static void beforeClass(){
// 构造并注入Mock对象ICmsProxyService
sceneConfigService.setAccessService(accessService);
}
  5.监听器方式代码
  5.1  实现监听器
  继承DependencyInjectionTestExecutionListener类,
  实现injectDependencies(TestContexttestContext)方法
public class MockitoDependencyInjectionTestExecutionListener extends
DependencyInjectionTestExecutionListener {
@Override
protected void injectDependencies(TestContext testContext) throws Exception {
super.injectDependencies(testContext);
init(testContext);
}
  5.2 利用反射注入mock对象
private void init(final TestContext testContext)throws Exception {
Object bean = testContext.getTestInstance();
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if(annotationinstanceof Mock){
//注入Mock实例
MockObject obj = new MockObject();
obj.setType(field.getType());
obj.setObj(Mockito.mock(field.getType()));
field.setAccessible(true);
field.set(bean, obj.getObj());
mockObjectMap.put(field.getName(), obj);
}else if(annotation instanceofAutowired){
injectFields.add(field);
}
}
}
AutowireCapableBeanFactory factory =testContext.getApplicationContext().getAutowireCapableBeanFactory();
//Autowired注解注入mock对象
for (Field field :injectFields) {
field.setAccessible(true);
Object object = field.get(bean);
if(objectinstanceof Proxy){
Class targetClass = AopUtils.getTargetClass(object);
if(targetClass ==null)
return;
Field[] targetFields =targetClass.getDeclaredFields();
for(Field targetField : targetFields){
targetField.setAccessible(true);
if(mockObjectMap.get(targetField.getName()) ==null){
continue;
}
targetField.set(getTargetObject(object,mockObjectMap.get(targetField.getName()).getType()),mockObjectMap.get(targetField.getName()).getObj());
}
}else{
Object realObject = factory.getBean(field.getName());
if(null != realObject){
Method[] methods = realObject.getClass().getDeclaredMethods();
for (Method method : methods) {
if(method.getName().equalsIgnoreCase("set" +field.getName())){
method.invoke(realObject, mockObjectMap.get(field.getName()).getObj());
}
}
}
}
}
}
  5.3 测试类配置
  使用@TestExecutionListeners注解,引入监听器,需要mock的对象加上@Mock注解。
@TestExecutionListeners({MockitoDependencyInjectionTestExecutionListener.class})
public class AccessServiceImplTest extends BaseTestCase{
@Autowired
private IAccessServiceaccessService;
@Mock
private IPersonServicepersonService;
@Mock
private IAccessDaoaccessDao;
}
  6.总结
  监听器的方式解放了代码中硬编码注入mock对象,使得代码简洁干净。

最新文章

  1. poj分类
  2. 搭建的SSH 框架
  3. IOS 入门开发教程
  4. Hibernate,JPA注解@OneToMany_Map
  5. WM_INITDIALOG与WM_CREATE消息的区别
  6. vim/Gvim配置
  7. Android-RecyclerView-Item点击事件设置
  8. 一步一步学python(四) - 字典
  9. KafKa介绍(分布式架构)
  10. python 标准模块 string
  11. datePicker.js 应用
  12. 【RL-TCPnet网络教程】第21章 RL-TCPnet之高效的事件触发框架
  13. EOS行为核心:解析插件chain_plugin
  14. for循环实例
  15. java中的锁之AbstractQueuedSynchronizer源码分析(二)
  16. AndroidKiller报.smali文件丢失问题解决(关闭Android Studio的Instant Run)
  17. CentOS7.1 Liberty云平台之环境准备(2)
  18. linux ifconfig -a
  19. MySql 几个小技巧
  20. Numpy 的常用操作

热门文章

  1. STM32F4XX devices vector table for EWARM toolchain.
  2. java中Keytool的使用总结
  3. ASIHTTPRequest系列(一):同步和异步请求
  4. 【GitLab】【GitHub】GitLab和GitHub的双向同步
  5. Step Detector and Step Counter Sensors on Android
  6. Fidder发送Get、POST请求
  7. 基于CentOS的MySQL学习补充三--使用Shell批量创建数据库表
  8. Linux学习2-在阿里云服务器上部署禅道环境
  9. 树莓派2B安装Xware迅雷远程下载
  10. springboot redis多数据源设置