2012-09-18 28 views
1

在我們的單元測試特定的服務,我們通常配置所有依賴關係EasyMocks ...和配置它們...在Spring上下文XML文件,我們需要添加這些依賴這樣的東西 -使用模擬對象,如果沒有找到

<bean id="myService" class="mypackage.EasyMockNiceCreator"> 
     <property name="iface" 
        value="myservicePackage.MyService"/> 
</bean> 

其中EasyMockNiceCreator是它創建了一個EasyMock.createNiceMock的FactoryBean的實現()在getObject()方法。

我怎樣才能讓這個默認的配置,讓春天會使用此配置,如果它沒有找到一個明確定義的自動裝配Autowired依賴,回退。

回答

1

我認爲這個代碼將幫助 -

自動豆創作者

import com.google.common.collect.Iterables; 
import org.springframework.beans.BeansException; 
import org.springframework.beans.MutablePropertyValues; 
import org.springframework.beans.PropertyValue; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.config.BeanDefinition; 
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 
import org.springframework.beans.factory.support.BeanDefinitionRegistry; 
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; 
import org.springframework.beans.factory.support.RootBeanDefinition; 

import java.lang.reflect.Field; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Collection; 
import java.util.List; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class AutoBeanDeclarer implements BeanDefinitionRegistryPostProcessor { 

    private Collection<String> mockedDefinitions; 

    public AutoBeanDeclarer() { 
     mockedDefinitions = new ArrayList<String>(); 
    } 

    private Iterable<Field> findAllAutoWired(Class targetBean) { 
     List<Field> declaredFields = Arrays.asList(targetBean.getDeclaredFields()); 
     return Iterables.filter(declaredFields, new Predicate<Field>() { 
      @Override 
      public boolean apply(Field input) { 
       return input.isAnnotationPresent(Autowired.class); 
      } 
     }); 
    } 

    private void registerOn(final BeanDefinitionRegistry registry,final String beanName, final Class type){ 
     RootBeanDefinition definition = new RootBeanDefinition(MocksFactory.class); 

     MutablePropertyValues values = new MutablePropertyValues(); 
     values.addPropertyValue(new PropertyValue("type", type)); 
     definition.setPropertyValues(values); 

     registry.registerBeanDefinition(beanName, definition); 
    } 

    @Override 
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { 
     for(String beanName: registry.getBeanDefinitionNames()) { 
      BeanDefinition beanDefinition = registry.getBeanDefinition(beanName); 
      String beanClassName = beanDefinition.getBeanClassName(); 
      try { 
       Class beanClass = Class.forName(beanClassName); 
       for (final Field field : findAllAutoWired(beanClass)) { 
        String fieldName = field.getName(); 
        boolean invalidType = field.getType().isArray() || field.getType().isPrimitive(); 
        if(invalidType) { 
         continue; 
        } 
        if(!registry.isBeanNameInUse(fieldName)) { 
         registerOn(registry, fieldName, field.getType()); 
         mockedDefinitions.add(fieldName); 
         // Now field will be available for autowiring. 
        } 
       } 
      } catch (ClassNotFoundException ex) { 
       Logger.getLogger(AutoBeanDeclarer.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
    } 

    @Override 
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 
     for(String beanName: mockedDefinitions) { 
      if(!beanFactory.containsBean(beanName)) { 
       Logger.getLogger(AutoBeanDeclarer.class.getName()).log(Level.SEVERE, "Missing definition %s", beanName); 
      } 
     } 
    } 
} 

模擬工廠類

import org.mockito.Mockito; 
import org.springframework.beans.factory.FactoryBean; 

public class MocksFactory implements FactoryBean { 

    private Class type;// the created object type 

    public void setType(final Class type) { 
     this.type = type; 
    } 

    @Override 
    public Object getObject() throws Exception { 
     return Mockito.mock(type); 
    } 

    @Override 
    public Class getObjectType() { 
     return type; 
    } 

    @Override 
    public boolean isSingleton() { 
     return true; 
    } 
} 

的context.xml

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> 

    <bean id="autoConfigurer" class="....AutoBeanFinder"></bean> 

    <bean id="targetClass" class="....Target"></bean> 

</beans> 

在Target類中自動裝配的所有服務都會被模擬。