Spring Batch : How to instantiate "Step" scope bean in Cucumber Testing?

2k views Asked by At

How to instantiate "Step" scope bean of spring in Cucumber Testing?

SpringJUnit4ClassRunner uses @TestExecutionListeners to instantiate the step scoped beans for testing purpose.

I am trying get this behavior in Cucumber. Cucumber uses a @RunWith(Cucumber.class)

Is there anyway we can instantiate step scope bean?

Thanks in advance

2

There are 2 answers

1
adam On

I'm not familiar with Cucumber, but I have instantiated/tested step scope items using @RunWith(SpringJUnit4ClassRunner.class)

I would recommend including the StepScopeTestExecutionListener.class as well as the DependencyInjectionTestExecutionListener (if you're injecting any dependencies) in your @TestExecutionListeners annotation, e.g. @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, StepScopeTestExecutionListener.class })

In order to instantiate a step scope bean in the test class, first get an instance of the ExecutionContext by utilizing the MetaDataInstanceFactory.

For example:

ExecutionContext executionContext = MetaDataInstanceFactory.createJobExecution().getExecutionContext();

Once you can have an instance of the ExecutionContext, you'll need to make use of the JobLauncherTestUtils class (documentation: http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/test/JobLauncherTestUtils.html). You can launch a step by calling launchStep(), for example:

jobLauncherTestUtils.launchStep(<step_name>, <job_parameters>, <execution_context>);

Hope that helps!

0
Dinkar Kolhe On

By exploring some options i have made it workable for now.

Below is my workaround

Bean Configuration

@Bean(name = "abc")
@StepScope
public ABC getABC(){
return new ABC();
}

@ContextConfiguration(classes = AppConfiguration.class, loader = AnnotationConfigContextLoader.class)
public class StepDef {

@Autowire
ABC abc;

public StepDef{

         StepExecution stepExecution = getStepExecution();
         StepSynchronizationManager.register(stepExecution);

}

}

I am not sure how correct is this implementation. I have initialize the StepExecution to load my configuration in stepDef Constructor so my AutoWiring can work properly and i can run my test against it.

I need to follow same approach for all stepDef , may be i will write a super class and implement that in super constructor.

Do let me know if you see any concerns.

Thanks again