- Revision
- 1563
- Author
- mauro
- Date
- 2010-02-08 10:05:28 -0600 (Mon, 08 Feb 2010)
Log Message
JBEHAVE-240: Added Spring support for composition of Steps class dependency injection.
Modified Paths
Added Paths
- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/
- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/SpringTraderScenario.java
- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/scenarios/
- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/scenarios/WildcardSearch.java
- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/scenarios/wildcard_search.scenario
- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/steps.xml
- trunk/core/jbehave-spring/
- trunk/core/jbehave-spring/pom.xml
- trunk/core/jbehave-spring/src/
- trunk/core/jbehave-spring/src/behaviour/
- trunk/core/jbehave-spring/src/behaviour/java/
- trunk/core/jbehave-spring/src/behaviour/java/org/
- trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/
- trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/
- trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/
- trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/
- trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/SpringStepsFactoryBehaviour.java
- trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/steps-with-dependency.xml
- trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/steps-with-missing-dependency.xml
- trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/steps.xml
- trunk/core/jbehave-spring/src/main/
- trunk/core/jbehave-spring/src/main/java/
- trunk/core/jbehave-spring/src/main/java/org/
- trunk/core/jbehave-spring/src/main/java/org/jbehave/
- trunk/core/jbehave-spring/src/main/java/org/jbehave/scenario/
- trunk/core/jbehave-spring/src/main/java/org/jbehave/scenario/steps/
- trunk/core/jbehave-spring/src/main/java/org/jbehave/scenario/steps/spring/
- trunk/core/jbehave-spring/src/main/java/org/jbehave/scenario/steps/spring/SpringStepsFactory.java
Diff
Modified: trunk/core/examples/trader/pom.xml (1562 => 1563)
--- trunk/core/examples/trader/pom.xml 2010-02-08 13:25:16 UTC (rev 1562) +++ trunk/core/examples/trader/pom.xml 2010-02-08 16:05:28 UTC (rev 1563) @@ -15,6 +15,11 @@ <artifactId>jbehave-pico</artifactId> <version>${jbehave.version}</version> </dependency> + <dependency> + <groupId>org.jbehave</groupId> + <artifactId>jbehave-spring</artifactId> + <version>${jbehave.version}</version> + </dependency> </dependencies> <build> <resources>
Added: trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/SpringTraderScenario.java (0 => 1563)
--- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/SpringTraderScenario.java (rev 0) +++ trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/SpringTraderScenario.java 2010-02-08 16:05:28 UTC (rev 1563) @@ -0,0 +1,28 @@ +package org.jbehave.examples.trader.spring; + +import org.jbehave.examples.trader.TraderScenario; +import org.jbehave.scenario.RunnableScenario; +import org.jbehave.scenario.steps.CandidateSteps; +import org.jbehave.scenario.steps.StepsConfiguration; +import org.jbehave.scenario.steps.spring.SpringStepsFactory; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class SpringTraderScenario extends TraderScenario { + + public SpringTraderScenario(Class<? extends RunnableScenario> scenarioClass) { + super(scenarioClass); + } + + @Override + protected CandidateSteps[] createSteps(StepsConfiguration configuration) { + ListableBeanFactory parent = createBeanFactory(); + return new SpringStepsFactory(configuration, parent).createCandidateSteps(); + } + + private ListableBeanFactory createBeanFactory() { + return (ListableBeanFactory) new ClassPathXmlApplicationContext( + new String[] { "org/jbehave/examples/trader/spring/steps.xml" }); + } + +}
Added: trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/scenarios/WildcardSearch.java (0 => 1563)
--- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/scenarios/WildcardSearch.java (rev 0) +++ trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/scenarios/WildcardSearch.java 2010-02-08 16:05:28 UTC (rev 1563) @@ -0,0 +1,12 @@ +package org.jbehave.examples.trader.spring.scenarios; + +import org.jbehave.examples.trader.spring.SpringTraderScenario; + + +public class WildcardSearch extends SpringTraderScenario { + + public WildcardSearch() { + super(WildcardSearch.class); + } + +}
Added: trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/scenarios/wildcard_search.scenario (0 => 1563)
--- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/scenarios/wildcard_search.scenario (rev 0) +++ trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/scenarios/wildcard_search.scenario 2010-02-08 16:05:28 UTC (rev 1563) @@ -0,0 +1,19 @@ +Scenario: Traders can be searched by name. This is the same scenario as +org.jbehave.examples.trader.scenarios.wildcard_search, with the only difference that +the candidate steps class (TraderSteps) is created, with it dependency, via a PicoContainer. + +Given the traders: +|name|rank| +|Larry|Stooge 3| +|Moe|Stooge 1| +|Curly|Stooge 2| +!-- This is a comment, which will be ignored in the execution +When a wildcard search ".*y" is executed +!-- This is another comment, also ignored, +but look Ma! I'm on a new line! +Then the traders returned are: +|name|rank| +|Larry|Stooge 3| +|Curly|Stooge 2| + +
Added: trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/steps.xml (0 => 1563)
--- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/steps.xml (rev 0) +++ trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/spring/steps.xml 2010-02-08 16:05:28 UTC (rev 1563) @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> + + <bean id="tradingService" class="org.jbehave.examples.trader.service.TradingService"> + </bean> + + <bean id="traderSteps" class="org.jbehave.examples.trader.TraderSteps"> + <constructor-arg ref="tradingService" /> + </bean> + + <bean id="beforeAndAfterSteps" class="org.jbehave.examples.trader.BeforeAfterSteps"> + </bean> + +</beans> \ No newline at end of file
Modified: trunk/core/examples/trader-test-scope/pom.xml (1562 => 1563)
--- trunk/core/examples/trader-test-scope/pom.xml 2010-02-08 13:25:16 UTC (rev 1562) +++ trunk/core/examples/trader-test-scope/pom.xml 2010-02-08 16:05:28 UTC (rev 1563) @@ -15,6 +15,11 @@ <artifactId>jbehave-pico</artifactId> <version>${jbehave.version}</version> </dependency> + <dependency> + <groupId>org.jbehave</groupId> + <artifactId>jbehave-spring</artifactId> + <version>${jbehave.version}</version> + </dependency> </dependencies> <build> <!-- JBEHAVE-155: we can run scenarios in test scope -->
Property changes: trunk/core/jbehave-spring
Name: svn:ignore
+ target
Added: trunk/core/jbehave-spring/pom.xml (0 => 1563)
--- trunk/core/jbehave-spring/pom.xml (rev 0) +++ trunk/core/jbehave-spring/pom.xml 2010-02-08 16:05:28 UTC (rev 1563) @@ -0,0 +1,31 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.jbehave</groupId> + <artifactId>jbehave</artifactId> + <version>2.5-SNAPSHOT</version> + </parent> + <artifactId>jbehave-spring</artifactId> + <name>JBehave Spring Support</name> + <description>Extension of JBehave Core that allows CandidateSteps instances to be composed using Spring</description> + + <dependencies> + <dependency> + <groupId>org.jbehave</groupId> + <artifactId>jbehave-core</artifactId> + <version>${pom.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + <version>2.5.6</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <version>2.5.6</version> + </dependency> + </dependencies> + +</project>
Added: trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/SpringStepsFactoryBehaviour.java (0 => 1563)
--- trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/SpringStepsFactoryBehaviour.java (rev 0) +++ trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/SpringStepsFactoryBehaviour.java 2010-02-08 16:05:28 UTC (rev 1563) @@ -0,0 +1,88 @@ +package org.jbehave.scenario.steps.spring; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.lang.reflect.Field; + +import org.jbehave.scenario.annotations.Given; +import org.jbehave.scenario.steps.CandidateSteps; +import org.jbehave.scenario.steps.Steps; +import org.jbehave.scenario.steps.StepsConfiguration; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class SpringStepsFactoryBehaviour { + + private static Field stepsInstance; + + @Before + public void setUp() throws NoSuchFieldException { + stepsInstance = Steps.class.getDeclaredField("instance"); + stepsInstance.setAccessible(true); + } + + private ListableBeanFactory createBeanFactory(String... xmlResources) { + return (ListableBeanFactory)new ClassPathXmlApplicationContext(xmlResources); + } + + @Test + public void ensureThatStepsCanBeCreated() throws NoSuchFieldException, IllegalAccessException { + // Given + ListableBeanFactory parent = createBeanFactory("org/jbehave/scenario/steps/spring/steps.xml"); + SpringStepsFactory factory = new SpringStepsFactory(new StepsConfiguration(), parent); + // When + CandidateSteps[] steps = factory.createCandidateSteps(); + // Then + assertFooStepsFound(steps); + } + + + @Test + public void ensureThatStepsWithStepsWithDependencyCanBeCreated() throws NoSuchFieldException, IllegalAccessException { + ListableBeanFactory parent = createBeanFactory("org/jbehave/scenario/steps/spring/steps-with-dependency.xml"); + // When + SpringStepsFactory factory = new SpringStepsFactory(new StepsConfiguration(), parent); + CandidateSteps[] steps = factory.createCandidateSteps(); + // Then + assertFooStepsFound(steps); + assertEquals(42, (int) ((FooStepsWithDependency) stepsInstance.get(steps[0])).integer); + } + + private void assertFooStepsFound(CandidateSteps[] steps) throws NoSuchFieldException, IllegalAccessException { + assertEquals(1, steps.length); + assertTrue(steps[0] instanceof CandidateSteps); + Object instance = stepsInstance.get(steps[0]); + assertTrue(instance instanceof FooSteps); + } + + + @Test(expected=BeanDefinitionStoreException.class) + public void ensureThatStepsWithMissingDependenciesCannotBeCreated() throws NoSuchFieldException, IllegalAccessException { + ListableBeanFactory parent = createBeanFactory("org/jbehave/scenario/steps/spring/steps-with-missing-depedency.xml"); + SpringStepsFactory factory = new SpringStepsFactory(new StepsConfiguration(), parent); + // When + factory.createCandidateSteps(); + // Then ... expected exception is thrown + } + + public static class FooSteps { + + @Given("a step with a $param") + public void aStepWithAParam(String param) { + } + + } + + public static class FooStepsWithDependency extends FooSteps { + private final Integer integer; + + public FooStepsWithDependency(Integer integer) { + this.integer = integer; + } + + } +}
Added: trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/steps-with-dependency.xml (0 => 1563)
--- trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/steps-with-dependency.xml (rev 0) +++ trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/steps-with-dependency.xml 2010-02-08 16:05:28 UTC (rev 1563) @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> + + <bean id="fooStepsWithDependency" class="org.jbehave.scenario.steps.spring.SpringStepsFactoryBehaviour$FooStepsWithDependency"> + <constructor-arg value="42"/> + </bean> + +</beans> \ No newline at end of file
Added: trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/steps-with-missing-dependency.xml (0 => 1563)
--- trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/steps-with-missing-dependency.xml (rev 0) +++ trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/steps-with-missing-dependency.xml 2010-02-08 16:05:28 UTC (rev 1563) @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> + + <bean id="fooStepsWithDependency" class="org.jbehave.scenario.steps.spring.SpringStepsFactoryBehaviour$FooStepsWithDependency"> + </bean> + +</beans> \ No newline at end of file
Added: trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/steps.xml (0 => 1563)
--- trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/steps.xml (rev 0) +++ trunk/core/jbehave-spring/src/behaviour/java/org/jbehave/scenario/steps/spring/steps.xml 2010-02-08 16:05:28 UTC (rev 1563) @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> + + <bean id="fooSteps" class="org.jbehave.scenario.steps.spring.SpringStepsFactoryBehaviour$FooSteps"> + </bean> + +</beans> \ No newline at end of file
Added: trunk/core/jbehave-spring/src/main/java/org/jbehave/scenario/steps/spring/SpringStepsFactory.java (0 => 1563)
--- trunk/core/jbehave-spring/src/main/java/org/jbehave/scenario/steps/spring/SpringStepsFactory.java (rev 0) +++ trunk/core/jbehave-spring/src/main/java/org/jbehave/scenario/steps/spring/SpringStepsFactory.java 2010-02-08 16:05:28 UTC (rev 1563) @@ -0,0 +1,52 @@ +package org.jbehave.scenario.steps.spring; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import org.jbehave.scenario.steps.CandidateSteps; +import org.jbehave.scenario.steps.Steps; +import org.jbehave.scenario.steps.StepsConfiguration; +import org.springframework.beans.factory.ListableBeanFactory; + +/** + * A factory class for {...@link CandidateSteps} that uses a + * {...@link ListableBeanFactory} for the composition and instantiation of all + * components that contains scenario annotated methods. + * + * @author Mauro Talevi + */ +public class SpringStepsFactory { + + private final StepsConfiguration configuration; + private final ListableBeanFactory parent; + + public SpringStepsFactory(StepsConfiguration configuration, ListableBeanFactory parent) { + this.configuration = configuration; + this.parent = parent; + } + + public CandidateSteps[] createCandidateSteps() { + List<Steps> steps = new ArrayList<Steps>(); + for (String name : parent.getBeanDefinitionNames()) { + Object bean = parent.getBean(name); + if (containsScenarioAnnotations(bean.getClass())) { + steps.add(new Steps(configuration, bean)); + } + } + return steps.toArray(new CandidateSteps[steps.size()]); + } + + private boolean containsScenarioAnnotations(Class<?> componentClass) { + for (Method method : componentClass.getMethods()) { + for (Annotation annotation : method.getAnnotations()) { + if (annotation.annotationType().getName().startsWith("org.jbehave.scenario.annotations")) { + return true; + } + } + } + return false; + } + +}
Modified: trunk/core/pom.xml (1562 => 1563)
--- trunk/core/pom.xml 2010-02-08 13:25:16 UTC (rev 1562) +++ trunk/core/pom.xml 2010-02-08 16:05:28 UTC (rev 1563) @@ -12,9 +12,10 @@ <modules> <module>jbehave-core</module> - <module>jbehave-pico</module> <module>jbehave-ant</module> <module>jbehave-maven-plugin</module> + <module>jbehave-pico</module> + <module>jbehave-spring</module> </modules> <dependencyManagement>
To unsubscribe from this list please visit:
