我与读者和作家有Chunk Tasklet
,我正在尝试对其进行单元测试,但我面临多个问题。
我使用了以下问题的答案来帮助创建我的单元测试:
如何使用代码
在tasklet中定义弹簧批处理块 它似乎是最接近我想要做的。
@ContextConfiguration(locations = { "classpath:config/beans-unittest-service.xml",
"classpath:config/beans-unittest-item.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
public class KpiMetricFromCsvFileTaskletTest extends RegistryServiceImplTest {
@Autowired
@Qualifier("kpiMetricCsvItemReader")
ItemReader<KpiMetric> reader;
@Autowired
@Qualifier("kpiMetricCreatorWriter")
KpiMetricCreatorWriter writer;
@Override
@Before
public void init() {
writer.setRegistryService(registryService);
writer.setRegistry(registry);
setCreateKpiMeasureBehaviour();
}
private ChunkContext createChunkContext() {
StepExecution stepExecution = Mockito.mock(StepExecution.class);
StepContext stepContext = Mockito.mock(StepContext.class);
ChunkContext chunkContext = Mockito.mock(ChunkContext.class);
JobExecution jobExecution = MetaDataInstanceFactory.createJobExecution();
Mockito.when(chunkContext.getStepContext()).thenReturn(stepContext);
Mockito.when(stepContext.getStepExecution()).thenReturn(stepExecution);
Mockito.when(stepExecution.getJobExecution()).thenReturn(jobExecution);
return chunkContext;
}
@Test
public void testTasklet() throws Exception {
StepContribution contribution = Mockito.mock(StepContribution.class);
ChunkContext chunkContext = createChunkContext();
Tasklet tasklet = new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
KpiMetric kpi = reader.read();
List<KpiMetric> items = new ArrayList<>();
while (kpi != null) {
items.add(kpi);
}
writer.write(items);
return RepeatStatus.FINISHED;
}
};
tasklet.execute(contribution, chunkContext);
}
}
- 我的单元测试
Class
扩展了另一个Class
,其中包含将设置模拟对象行为的方法。 - 我有两个配置文件。其中一个包含读取器豆
kpiMetricCsvItemReader
和作家豆kpiMetricCreatorWriter
。 - 在我的单元测试
init
方法中,我将编写器的服务属性更改为模拟服务对象,我也模拟上下文对象,就像上面链接的答案一样。
问题是,在testTasklet
方法中,我想创建一个 Tasklet 并执行它,但是当我运行程序时,我收到错误:
org.springframework.batch.item.ReaderNotOpenException:读取器必须先打开,然后才能读取。
我知道该文件没有打开,但是当我使用 Spring 批处理启动作业时,我没有收到该错误,因此 Spring 应该自行打开我的文件。
现在为了解决这个问题,我应该设法为读者打开文件,或者将 tasklet 的创建委托给其他可以处理它的东西,但是如何呢?
编辑
也许显示读取器配置文件应该会有所帮助:
<bean id="kpiMetricCsvItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="classpath:${kpiMetricCsvFile}" />
<property name="linesToSkip" value="1"/>
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value=";"/>
<property name="names" value="key,description,name,score,tool,variable_type" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="com.example.fieldmapper.KpiMetricFieldSetMapper" />
</property>
</bean>
</property>
</bean>
<bean id="kpiMetricCreatorWriter" class="com.example.writer.kpi.KpiMetricCreatorWriter" >
<property name="registry" ref="registry" />
<property name="registryService" ref="registryService" />
</bean>
在面向块的步骤之外使用时,应手动打开/关闭项目读取器/写入器。因此,在您的情况下,您需要在使用读取数据之前自己打开阅读器。
您可以参考 FlatFileItemReader 本身的单元测试作为示例。