zoukankan      html  css  js  c++  java
  • 基于spring与mockito单元测试Mock对象注入

    转载: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对象,使得代码简洁干净。
  • 相关阅读:
    我的JAVA之旅(二)初识JAVA
    ORACLE并发处理
    我的JAVA之旅(一)安装配置
    我的JAVA之旅(三) 元素语法
    改变一生的五句话
    InstallShield集成安装MSDE2000最小版本(三) fishout特许授权发布
    IS2009修改XML File 奕婷特许授权发布
    SQL Server中多个表格求出相同列和不同列(答案来自CSDN上SQL专家的回答)
    InstallShield集成安装MSDE2000最小版本(二) fishout特许授权发布
    Installshield停止操作系统进程的代码 IS6及以上版本适用
  • 原文地址:https://www.cnblogs.com/ceshi2016/p/9546703.html
Copyright © 2011-2022 走看看