Some days ago I wrote a post on how to test a JBatch batch more easily making it synchronous (+ few other features). BatchEE proposal goes today one step further allowing to test steps!
The idea is based on two classes: StepLauncher and StepBuilder.
The first one has a unique method called execute taking a Step representing the step you want to test and (optionnally) properties representing the job parameters. It returns the StepExecution which makes easy to validate the execution itself.
Here are some samples:
final StepExecution execution = StepLauncher.execute(myStep); assertEquals("awesome execution", execution.getExitStatus()); assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus());
final StepExecution execution = StepLauncher.execute( myStep, new Properties() {{ setProperty("conf", "xxxx"); }});
In this last sample myStep can use as step properties #{jobParameters[‘conf’]} which would be replaced by “xxxx”.
So great we can execute steps but how to create them? Of course Step is a jaxb object so you can just do a new then setXXXX N times but it is not nice and it would link you to more than simply a type which could be an issue (basically jaxb behavior, default batchee choices etc…). To avoid it StepBuilder is proposed. It allows you to build batchlet and chunk steps.
Like snippets are more efficient than words here it is:
// simple batchlet without properties StepBuilder.newBatchlet().ref("org.superbiz.MyBatchlet").create(); // batchlet with config StepBuilder.newBatchlet() .ref("org.superbiz.MyBatchlet") .property("config1", "override") .property("config2", "#{jobParameters['conf']}") .create() // chunk: all components can use .property(k, v) StepBuilder.newChunk() .reader().ref(SimpleReader.class.getName()) .property("file", "#{jobParameters['input']}") .processor().ref(SimpleProcessor.class.getName()) .writer().ref(SimpleWriter.class.getName()) .create())
And if you just want to reuse a step from you job xml descriptors:
// search META-INF/batch-jobs/myjob.xml, .xml is optional StepBuilder.extractFromXml("myjob.xml", "domy-step-nameSleep");
Putting it together here is a full test:
@Test public void stepFromXml() { final StepExecution execution = StepLauncher.execute(StepBuilder.extractFromXml("sleep.xml", "doSleep")); assertEquals("OK", execution.getExitStatus()); assertEquals(BatchStatus.COMPLETED, execution.getBatchStatus()); }