Add a new annotation @SpringBatchTest to simplify testing

This commit adds a new annotation `@SpringBatchTest` that:

* configures two beans `JobLauncherTestUtils` and `JobRepositoryTestUtils`
in the test context.

* imports the `StepScopeTestExecutionListener` and
`JobScopeTestExecutionListener` as test execution listeners.

Resolves BATCH-2718
This commit is contained in:
Mahmoud Ben Hassine
2018-05-17 13:31:41 +02:00
committed by Michael Minella
parent 98070e4a1c
commit 0dab67c936
10 changed files with 536 additions and 9 deletions

View File

@@ -28,19 +28,24 @@ In order for the unit test to run a batch job, the framework must
this behavior:
* `@RunWith(SpringJUnit4ClassRunner.class)`:
* `@RunWith(SpringRunner.class)`:
Indicates that the class should use Spring's JUnit facilities
* `@ContextConfiguration(...)`:
Indicates which resources to configure the `ApplicationContext` with.
The following example shows the two annotations in use:
Starting from v4.1, it is also possible to inject Spring Batch test utilities
like the `JobLauncherTestUtils` and `JobRepositoryTestUtils` in the test context
using the `@SpringBatchTest` annotation.
The following example shows the annotations in use:
.Using Java Configuration
[source, java, role="javaContent"]
----
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBatchTest
@RunWith(SpringRunner.class)
@ContextConfiguration(classes=SkipSampleConfiguration.class)
public class SkipSampleFunctionalTests { ... }
----
@@ -48,7 +53,8 @@ public class SkipSampleFunctionalTests { ... }
.Using XML Configuration
[source, java, role="xmlContent"]
----
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBatchTest
@RunWith(SpringRunner.class)
@ContextConfiguration(locations = { "/simple-job-launcher-context.xml",
"/jobs/skipSampleJob.xml" })
public class SkipSampleFunctionalTests { ... }
@@ -81,7 +87,8 @@ In the following example, the batch job reads from the database and
.XML Based Configuration
[source, java, role="xmlContent"]
----
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBatchTest
@RunWith(SpringRunner.class)
@ContextConfiguration(locations = { "/simple-job-launcher-context.xml",
"/jobs/skipSampleJob.xml" })
public class SkipSampleFunctionalTests {
@@ -115,7 +122,8 @@ public class SkipSampleFunctionalTests {
.Java Based Configuration
[source, java, role="javaContent"]
----
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBatchTest
@RunWith(SpringRunner.class)
@ContextConfiguration(classes=SkipSampleConfiguration.class)
public class SkipSampleFunctionalTests {
@@ -187,7 +195,7 @@ The listener is declared at the class level, and its job is to
@ContextConfiguration
@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class,
StepScopeTestExecutionListener.class })
@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringRunner.class)
public class StepScopeTestExecutionListenerIntegrationTests {
// This component is defined step-scoped, so it cannot be injected unless
@@ -195,7 +203,7 @@ public class StepScopeTestExecutionListenerIntegrationTests {
@Autowired
private ItemReader<String> reader;
public StepExecution getStepExection() {
public StepExecution getStepExecution() {
StepExecution execution = MetaDataInstanceFactory.createStepExecution();
execution.getExecutionContext().putString("input.data", "foo,bar,spam");
return execution;
@@ -222,6 +230,38 @@ There are two `TestExecutionListeners`. One
`StepExecution`). If a factory method is not provided,
then a default `StepExecution` is created.
Starting from v4.1, the `StepScopeTestExecutionListener` and
`JobScopeTestExecutionListener` are imported as test execution listeners
if the test class is annotated with `@SpringBatchTest`. The preceding test
example can be configured as follows:
[source, java]
----
@SpringBatchTest
@RunWith(SpringRunner.class)
@ContextConfiguration
public class StepScopeTestExecutionListenerIntegrationTests {
// This component is defined step-scoped, so it cannot be injected unless
// a step is active...
@Autowired
private ItemReader<String> reader;
public StepExecution getStepExecution() {
StepExecution execution = MetaDataInstanceFactory.createStepExecution();
execution.getExecutionContext().putString("input.data", "foo,bar,spam");
return execution;
}
@Test
public void testReader() {
// The reader is initialized and bound to the input data
assertNotNull(reader.read());
}
}
----
The listener approach is convenient if you want the duration of the
step scope to be the execution of the test method. For a more flexible
but more invasive approach, you can use the