Spring Batch备份作业测试异常:预期COMPLETED却返回UNKNOWN
看起来你的备份作业测试遇到了几个关键问题,导致作业没有执行实际步骤就结束,返回UNKNOWN状态。我帮你梳理一下核心问题和修复方案:
1. 作业配置中的步骤方法名笔误
你的作业配置里调用了fetchHeid(),但实际定义的步骤bean方法是fetchDomain(),这会导致作业没有关联到任何有效步骤,启动后直接结束,自然不会执行reader和writer,返回UNKNOWN状态。
修复代码:
@Bean public Job backupJob() throws Exception { return jobBuilderFactory.get("backupJob") .start(fetchDomain()) // 修正为正确的步骤方法名 .build(); }
2. 破坏@StepScope懒加载的错误调用方式
你在步骤配置中直接调用itemReader(null)来初始化reader,这完全绕过了Spring的@StepScope代理机制,不仅无法注入job参数id,还会创建一个无效的reader实例(参数为null),导致步骤无法正常执行。
修复方案:让Spring通过依赖注入来管理@StepScope的reader,而不是直接调用方法:
// 把itemReader作为参数注入到步骤配置方法中 @Bean public Step fetchDomain(JdbcPagingItemReader<DomainObject> itemReader) throws Exception { return stepBuilderFactory.get("fetchDomain") .<DomainObject, DomainObject>chunk(10) .faultTolerant() .reader(itemReader) // 直接使用注入的代理实例 .writer(items -> items.forEach(System.out::println)) .build(); }
这样Spring会在作业执行时,根据当前的job参数动态创建reader实例,正确注入id参数。
3. 确保JobLauncherTestUtils正确关联目标作业
虽然@SpringBatchTest会自动配置JobLauncherTestUtils,但当存在多个job或者自定义batch配置时,最好手动指定要测试的job,避免歧义:
在测试类中添加自定义JobLauncherTestUtils bean:
@RunWith(SpringRunner.class) @SpringBatchTest @ContextConfiguration(classes = {ApplicationBatchConfiguration.class}) public class BackupJobConfigurationTest { @Autowired @Qualifier("backupJob") private Job job; @Bean public JobLauncherTestUtils jobLauncherTestUtils() { JobLauncherTestUtils testUtils = new JobLauncherTestUtils(); testUtils.setJob(job); // 明确指定测试的作业 return testUtils; } @Autowired private JobLauncherTestUtils jobLauncherTestUtils; @Test public void flowTest() throws Exception { JobParameters parameters = new JobParametersBuilder() .addString("id", "124") .toJobParameters(); JobExecution execution = jobLauncherTestUtils.launchJob(parameters); assertEquals("COMPLETED", execution.getExitStatus().getExitCode()); } }
4. 验证非默认JobRepository schema的可用性
你的JobRepository使用了自定义表前缀BATCH_PROCESSING.BATCH_,请确保测试环境的数据库中存在这些表(如果是DB2,需要预先执行Spring Batch的DB2 schema脚本,并替换表前缀)。如果使用内存数据库进行测试,需要在测试配置中初始化这些表。
总结
最关键的两个问题是步骤方法名的笔误和**@StepScope bean的错误调用方式**,修复这两个问题后,作业应该能正常执行reader和writer,测试也会返回COMPLETED状态。
内容的提问来源于stack exchange,提问作者wtsiamruk

