创建名称为 'jobLauncherTestUtils' 的 bean 时出错:通过方法 'setJob' 表达的依赖关系不满足

Error creating bean with name 'jobLauncherTestUtils': Unsatisfied dependency expressed through method 'setJob'

我有一个配置为从一个数据库读取数据并写入另一个数据库的作业。我的 JobConfiguration 有一个具有此配置的 Job bean:

@Configuration
@EnableBatchProcessing
public class JobConfiguration {
    private static final String JOB_NAME = "loadCompanyCountryJob";
    private static final String STEP_NAME = "loadCompanyCountryStep";
    private static final int CHUNK_COMMIT_SIZE = 100;

    @Bean
    public Job job(JobBuilderFactory jobBuilderFactory,
                   StepBuilderFactory stepBuilderFactory,
                   ItemReader<SourceEntity> itemReader,
                   ItemProcessor<SourceEntity, DestinationEntity> itemProcessor,
                   ItemWriter<DestinationEntity> itemWriter
    ) {
        Step step = stepBuilderFactory.get(STEP_NAME)
                .<SourceEntity, DestinationEntity>chunk(CHUNK_COMMIT_SIZE)
                .reader(itemReader)
                .processor(itemProcessor)
                .writer(itemWriter)
                .build();
        return jobBuilderFactory.get(JOB_NAME)
                .incrementer(new RunIdIncrementer())
                .start(step)
                .build();
    }

}

现在我想为这个作业创建一个测试class:

@ExtendWith(SpringExtension.class)
@SpringBatchTest
@EnableAutoConfiguration
@ContextConfiguration(classes = JobConfiguration.class)
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
        DirtiesContextTestExecutionListener.class})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class SpringBatchJobTest {

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    @Autowired
    private JobRepositoryTestUtils jobRepositoryTestUtils;

    @Before
    public void clearJobExecutions() {
        this.jobRepositoryTestUtils.removeJobExecutions();
    }

    @Test
    public void givenReferenceOutput_whenJobExecuted_thenSuccess() throws Exception {
        // given
        JobParameters jobParameters = this.jobLauncherTestUtils.getUniqueJobParameters();

        // when
        JobExecution jobExecution = this.jobLauncherTestUtils.launchJob(jobParameters);
        JobInstance actualJobInstance = jobExecution.getJobInstance();
        ExitStatus actualJobExitStatus = jobExecution.getExitStatus();

        // then
        Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
    }
....

但是当我尝试开始测试时遇到错误:

Caused by: Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名称为 'job' 的 bean 在 com.closeupinternational.cpoprocessbatch.job.JobConfiguration 中定义时出错:通过方法 'job' 表达的不满足的依赖关系参数 2;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用类型 'org.springframework.batch.item.ItemReader<com.closeupinternational.cpoprocessbatch.data.source.SourceEntity>' 的符合条件的 bean:预计至少有 1 个符合自动装配候选条件的 bean。依赖注解:{}

我如何为这个工作创建测试?我用的是H2数据库模拟数据库。

根据日志消息,无法创建作业 bean,因为测试上下文中没有 ItemReader。您需要将生成 ItemReader 作为 bean 的配置 class 添加到 @ContextConfiguration 的字段 classes

我更改了 JobConfiguration 的实现:

    @Bean
    public Job job(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory
    ) {
        log.info("Called job configuration");
        return jobBuilderFactory.get(JOB_NAME)
                .incrementer(new RunIdIncrementer())
                .start(loadCompanyCountryStep(stepBuilderFactory))
                .build();
    }

    @Bean
    public Step loadCompanyCountryStep(StepBuilderFactory stepBuilderFactory){
        log.info("Called step configuration");
        return stepBuilderFactory.get(STEP_NAME)
                .<SourceEntity, DestinationEntity>chunk(CHUNK_COMMIT_SIZE)
                .reader(reader())
                .processor(processor())
                .writer(writer())
                .build();
    }

    @Bean
    public CompanyCountryItemReader reader() {
        log.info("Creating an CompanyCountryItemReader");
        return new CompanyCountryItemReader();
    }

    @Bean
    public CompanyCountryItemProcessor processor() {
        log.info("Creating an CompanyCountryItemProcessor");
        return new CompanyCountryItemProcessor();
    }

    @Bean
    public CompanyCountryItemWriter writer() {
        log.info("Creating an CompanyCountryItemWriter");
        return new CompanyCountryItemWriter();
    }