我正在尝试集成测试ItemReader - 这是类:
@Slf4j
public class StudioReader implements ItemReader<List<Studio>> {
@Setter private zoneDao zoneDao;
@Getter @Setter private BatchContext context;
private AreaApi areaApi = new AreaApi();
public List<Studio> read() throws Exception {
return areaApi.getStudioLocations();
}
这是我的bean.xml:
<bean class="org.springframework.batch.core.scope.StepScope" />
<bean id="ItemReader" class="com.sync.studio.reader.StudioReader" scope="step">
<property name="context" ref="BatchContext" />
<property name="zoneDao" ref="zoneDao" />
</bean>
这是我试图写的测试:
@ContextConfiguration(locations = {
"classpath:config/studio-beans.xml",
"classpath:config/test-context.xml"})
@TestExecutionListeners({
DependencyInjectionTestExecutionListener.class,
StepScopeTestExecutionListener.class })
public class StudioSyncReaderIT extends BaseTest {
@Autowired
private ItemReader<List<Studio>> reader;
public StepExecution getStepExecution() {
JobParameters jobParameters = new JobParametersBuilder()
.toJobParameters();
StepExecution execution = createStepExecution(
jobParameters);
return execution;
}
@Before
public void setUp() {
((ItemStream) reader).open(new ExecutionContext()); } //ClassCastException
@Test
@DirtiesContext
public void testReader() throws Exception {
assertNotNull(reader.read());
}
@After
public void tearDown() {
((ItemStream) reader).close(); //ClassCastException
}
}
我收到了java.lang.ClassCastException:com.sun.proxy。$ Proxy36无法在Before和After上强制转换为ItemReader。我错过了什么?还有什么我需要为此设置(例如,配置xml中的任何注释或条目)?
答案 0 :(得分:1)
您的问题是ItemReader
不是ItemStream
。如果您想将阅读器用作流,则StudioReader
需要实施org.springframework.batch.item.ItemStreamReader
。
import org.springframework.batch.item.ItemStreamReader;
public class StudioReader implements ItemStreamReader<List<Studio>>{
...
}
您可以使用Generic类型将类型T
设置为多个接口,以避免在@Before
&amp; @After
。
public class StudioSyncReaderIT<T extends ItemReader<List<Studio>> & ItemStream >
extends BaseTest {
@Autowired
private T reader;
@Before
public void setUp() {
reader.open(new ExecutionContext());
}
@After
public void tearDown() {
reader.close();
}
}
@ContextConfiguration
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, StepScopeTestExecutionListener.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class AutowireDependencyImplementedMultiInterfacesTest<T extends Supplier<List<String>> & Runnable & AutowireDependencyImplementedMultiInterfacesTest.Task> {
@Autowired
private T springTest;
@Test
public void inject() throws Throwable {
assertThat(springTest, is(not(instanceOf(MockTask.class))));
assertThat(springTest.get(), equalTo(singletonList("spring-test")));
springTest.hasBeenRan(false);
springTest.run();
springTest.hasBeenRan(true);
}
@Configuration
static class Config {
@Bean("step")
public StepScope stepScope() {
return new StepScope();
}
@Bean
@Scope(value = "step")
public MockTask task() {
return new MockTask("spring-test");
}
}
interface Task {
void hasBeenRan(boolean ran);
}
static class MockTask implements Supplier<List<String>>, Runnable, Task {
private final List<String> descriptions;
private boolean ran = false;
public MockTask(String... descriptions) {
this.descriptions = asList(descriptions);
}
@Override
public void run() {
ran = true;
}
@Override
public List<String> get() {
return descriptions;
}
public void hasBeenRan(boolean ran) {
assertThat(this.ran, is(ran));
}
}
}
答案 1 :(得分:0)
将XML配置和Java配置与Spring Batch结合使用时,最终会对如何为步骤范围bean创建代理产生一些困惑。将步骤范围的配置更改为以下内容:
<bean class="org.springframework.batch.core.scope.StepScope">
<property name="proxyTargetClass" value="true"/>
</bean>