All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cucumber.runtime.java.spring.SpringFactory Maven / Gradle / Ivy

There is a newer version: 1.2.6
Show newest version
package cucumber.runtime.java.spring;

import cucumber.runtime.CucumberException;
import cucumber.runtime.java.ObjectFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.ContextHierarchy;
import org.springframework.test.context.TestContextManager;

import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.HashSet;

/**
 * Spring based implementation of ObjectFactory.
 * 

*

*

    *
  • It uses TestContextManager to manage the spring context. * Configuration via: @ContextConfiguration or @ContextHierarcy * At least on step definition class needs to have a @ContextConfiguration or * @ContextHierarchy annotation. If more that one step definition class has such * an annotation, the annotations must be equal on the different step definition * classes. If no step definition class with @ContextConfiguration or * @ContextHierarcy is found, it will try to load cucumber.xml from the classpath. *
  • *
  • The step definitions class with @ContextConfiguration or @ContextHierarchy * annotation, may also have a @WebAppConfiguration or @DirtiesContext annotation. *
  • *
  • The step definitions added to the TestContextManagers context and * is reloaded for each scenario.
  • *
*

*

*

* Application beans are accessible from the step definitions using autowiring * (with annotations). *

*/ public class SpringFactory implements ObjectFactory { private ConfigurableListableBeanFactory beanFactory; private CucumberTestContextManager testContextManager; private final Collection> stepClasses = new HashSet>(); private Class stepClassWithSpringContext = null; public SpringFactory() { } @Override public void addClass(final Class stepClass) { if (!stepClasses.contains(stepClass)) { if (dependsOnSpringContext(stepClass)) { if (stepClassWithSpringContext == null) { stepClassWithSpringContext = stepClass; } else { checkAnnotationsEqual(stepClassWithSpringContext, stepClass); } } stepClasses.add(stepClass); } } private void checkAnnotationsEqual(Class stepClassWithSpringContext, Class stepClass) { Annotation[] annotations1 = stepClassWithSpringContext.getAnnotations(); Annotation[] annotations2 = stepClass.getAnnotations(); if (annotations1.length != annotations2.length) { throw new CucumberException("Annotations differs on glue classes found: " + stepClassWithSpringContext.getName() + ", " + stepClass.getName()); } for (Annotation annotation : annotations1) { if (!isAnnotationInArray(annotation, annotations2)) { throw new CucumberException("Annotations differs on glue classes found: " + stepClassWithSpringContext.getName() + ", " + stepClass.getName()); } } } private boolean isAnnotationInArray(Annotation annotation, Annotation[] annotations) { for (Annotation annotationFromArray: annotations) { if (annotation.equals(annotationFromArray)) { return true; } } return false; } @Override public void start() { if (stepClassWithSpringContext != null) { testContextManager = new CucumberTestContextManager(stepClassWithSpringContext); } else { if (beanFactory == null) { beanFactory = createFallbackContext(); } } notifyContextManagerAboutTestClassStarted(); if (beanFactory == null || isNewContextCreated()) { beanFactory = testContextManager.getBeanFactory(); for (Class stepClass : stepClasses) { registerStepClassBeanDefinition(beanFactory, stepClass); } } GlueCodeContext.INSTANCE.start(); } @SuppressWarnings("resource") private ConfigurableListableBeanFactory createFallbackContext() { ConfigurableApplicationContext applicationContext; if (getClass().getClassLoader().getResource("cucumber.xml") != null) { applicationContext = new ClassPathXmlApplicationContext("cucumber.xml"); } else { applicationContext = new GenericApplicationContext(); } applicationContext.registerShutdownHook(); ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory(); beanFactory.registerScope(GlueCodeScope.NAME, new GlueCodeScope()); for (Class stepClass : stepClasses) { registerStepClassBeanDefinition(beanFactory, stepClass); } return beanFactory; } private void notifyContextManagerAboutTestClassStarted() { if (testContextManager != null) { try { testContextManager.beforeTestClass(); } catch (Exception e) { throw new CucumberException(e.getMessage(), e); } } } private boolean isNewContextCreated() { if (testContextManager == null) { return false; } return !beanFactory.equals(testContextManager.getBeanFactory()); } private void registerStepClassBeanDefinition(ConfigurableListableBeanFactory beanFactory, Class stepClass) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; BeanDefinition beanDefinition = BeanDefinitionBuilder .genericBeanDefinition(stepClass) .setScope(GlueCodeScope.NAME) .getBeanDefinition(); registry.registerBeanDefinition(stepClass.getName(), beanDefinition); } @Override public void stop() { notifyContextManagerAboutTestClassFinished(); GlueCodeContext.INSTANCE.stop(); } private void notifyContextManagerAboutTestClassFinished() { if (testContextManager != null) { try { testContextManager.afterTestClass(); } catch (Exception e) { throw new CucumberException(e.getMessage(), e); } } } @Override public T getInstance(final Class type) { try { return beanFactory.getBean(type); } catch (BeansException e) { throw new CucumberException(e.getMessage(), e); } } private boolean dependsOnSpringContext(Class type) { boolean hasStandardAnnotations = annotatedWithSupportedSpringRootTestAnnotations(type); if(hasStandardAnnotations) { return true; } final Annotation[] annotations = type.getDeclaredAnnotations(); return (annotations.length == 1) && annotatedWithSupportedSpringRootTestAnnotations(annotations[0].annotationType()); } private boolean annotatedWithSupportedSpringRootTestAnnotations(Class type) { return type.isAnnotationPresent(ContextConfiguration.class) || type.isAnnotationPresent(ContextHierarchy.class); } } class CucumberTestContextManager extends TestContextManager { public CucumberTestContextManager(Class testClass) { super(testClass); registerGlueCodeScope(getContext()); } public ConfigurableListableBeanFactory getBeanFactory() { return getContext().getBeanFactory(); } private ConfigurableApplicationContext getContext() { return (ConfigurableApplicationContext)getTestContext().getApplicationContext(); } private void registerGlueCodeScope(ConfigurableApplicationContext context) { do { context.getBeanFactory().registerScope(GlueCodeScope.NAME, new GlueCodeScope()); context = (ConfigurableApplicationContext)context.getParent(); } while (context != null); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy