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对象,使得代码简洁干净。
  • 相关阅读:
    CodeForces
    CodeForces
    CodeForces
    【模板】POJ-1511(dijkstra堆优化+链式前向星)
    【模板】POJ-1502(dijkstra)
    P2862 [USACO06JAN]Corral the Cows G
    P2495 [SDOI2011]消耗战
    CF613D Kingdom and its Cities
    P4655 [CEOI2017]Building Bridges
    P3917 异或序列
  • 原文地址:https://www.cnblogs.com/ceshi2016/p/9546703.html
Copyright © 2011-2022 走看看