Introduction

Dependency Injection has become an integral part of any modern software design. We discuss here the different ways in which JBehave supports dependency injection.

JBehave supports the following dependency injection containers:

Fully-working examples of running stories with dependency-injection support can be found in the trader-[guice|pico|spring|weld] examples. Note that dependency injection examples only concentrate on the composition via the respective containers but do not replicate what is in the trader example. Indeed, they use the same stories and steps instances, simply configured in a different way.

Embedder class-level injection

Using Guice

When using Guice we can specify the inject from separate modules for configuration and steps.

Using PicoContainer

When using PicoContainer we can specify the container from separate modules for configuration and steps.

Using Spring

When using Spring, we can specify the context from separate locations for configuration and steps.

Using Weld

When using Weld you can inject configuration and steps using the standard Context and Dependency Injection (CDI) annotations

To override the JBehave configuration you write a producer method and annotate the method with an @WeldConfiguration

Steps class-level injection

Steps classes often use external dependencies to interface to the system whose behaviour is being verified.

Using Guice

CandidateSteps can be created with Guice using the GuiceStepsFactory:

where the StepsModule defines the steps classes and their scope:


    public static class StepsModule extends AbstractModule {

        @Override
        protected void configure() {
            bind(TradingService.class).in(Scopes.SINGLETON);
            bind(GuiceTraderSteps.class).in(Scopes.SINGLETON);
            bind(BeforeAfterSteps.class).in(Scopes.SINGLETON);
            bind(AndSteps.class).in(Scopes.SINGLETON);
            bind(CalendarSteps.class).in(Scopes.SINGLETON);
            bind(PendingSteps.class).in(Scopes.SINGLETON);
            bind(PriorityMatchingSteps.class).in(Scopes.SINGLETON);
            bind(SandpitSteps.class).in(Scopes.SINGLETON);
            bind(SearchSteps.class).in(Scopes.SINGLETON);
        }

    }

and the steps classes requiring injection are appropriately Guice-annotated:

public class GuiceTraderSteps extends TraderSteps {

    @Inject
    public GuiceTraderSteps(TradingService service) {
        super(service);
    }

}

Using PicoContainer

CandidateSteps can be created with PicoContainer using the PicoStepsFactory:

Using Spring

CandidateSteps can be created with Spring using the SpringStepsFactory:

Using Weld

CandidateSteps can be created by annotating a class using the @WeldStep annotation WeldStep:

where the steps class is appropriately Weld-annotated: