56 lines
3.7 KiB
HTML
56 lines
3.7 KiB
HTML
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:pls="http://www.w3.org/2005/01/pronunciation-lexicon" xmlns:ssml="http://www.w3.org/2001/10/synthesis" xmlns:svg="http://www.w3.org/2000/svg"><head><title>Testing Step-Scoped Components</title><link rel="stylesheet" type="text/css" href="docbook-epub.css"/><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"/><link rel="prev" href="ch10s03.xhtml" title="Testing Individual Steps"/><link rel="next" href="ch10s05.xhtml" title="Validating Output Files"/></head><body><header/><section class="section" title="Testing Step-Scoped Components" epub:type="subchapter" id="d5e3514"><div class="titlepage"><div><div><h2 class="title" style="clear: both">Testing Step-Scoped Components</h2></div></div></div><p>Often the components that are configured for your steps at runtime
|
|
use step scope and late binding to inject context from the step or job
|
|
execution. These are tricky to test as standalone components unless you
|
|
have a way to set the context as if they were in a step execution. That is
|
|
the goal of two components in Spring Batch: the
|
|
<code class="classname">StepScopeTestExecutionListener</code> and the
|
|
<code class="classname">StepScopeTestUtils</code>.</p><p>The listener is declared at the class level, and its job is to
|
|
create a step execution context for each test method. For example:</p><pre class="programlisting">@ContextConfiguration
|
|
@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class,
|
|
StepScopeTestExecutionListener.class })
|
|
@RunWith(SpringJUnit4ClassRunner.class)
|
|
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 getStepExection() {
|
|
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());
|
|
}
|
|
|
|
}</pre><p>There are two <code class="classname">TestExecutionListeners</code>, one
|
|
from the regular Spring Test framework and handles dependency injection
|
|
from the configured application context, injecting the reader, and the
|
|
other is the Spring Batch
|
|
<code class="classname">StepScopeTestExecutionListener</code>. It works by looking
|
|
for a factory method in the test case for a
|
|
<code class="classname">StepExecution</code>, and using that as the context for
|
|
the test method, as if that execution was active in a Step at runtime. The
|
|
factory method is detected by its signature (it just has to return a
|
|
<code class="classname">StepExecution</code>). If a factory method is not provided
|
|
then a default <code class="classname">StepExecution</code> is created.</p><p>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
|
|
<code class="classname">StepScopeTestUtils</code>. For example, to count the
|
|
number of items available in the reader above:</p><pre class="programlisting">int count = StepScopeTestUtils.doInStepScope(stepExecution,
|
|
new Callable<Integer>() {
|
|
public Integer call() throws Exception {
|
|
|
|
int count = 0;
|
|
|
|
while (reader.read() != null) {
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
});</pre></section><footer/></body></html> |