首页 > 解决方案 > 使用 Spring Boot 进行测试批处理

问题描述

我创建了一个批处理,一切运行良好我做了一些单元测试,它也运行良好我正在尝试按照 spring-batch 文档对我的批处理进行集成测试,但我不明白我的错误。

这是我的批处理配置

@Configuration
@EnableBatchProcessing
@EnableScheduling
@EnableTransactionManagement
@PropertySource(value="/batch.properties", ignoreResourceNotFound = false)
public class BatchConfiguration {

   @Autowired
   DataSource dataSource;
   @Autowired
   PlatformTransactionManager transactionManager;

   @Bean
   public JobRepository jobRepository() throws Exception {
       JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
       factory.setDataSource(dataSource);
       factory.setTransactionManager(transactionManager);
       factory.afterPropertiesSet();
       return (JobRepository) factory.getObject();
   }

   @Bean
   public SimpleJobLauncher jobLauncher(JobRepository jobRepository) {
      SimpleJobLauncher launcher = new SimpleJobLauncher();
       launcher.setJobRepository(jobRepository);
       return launcher;
   }

}

我的一批的一个例子

@Component
@AutomaticLogging
public class TimeoutFormJob {    
    @Autowired
    public JobBuilderFactory jobBuilderFactory;
    @Autowired
    public StepBuilderFactory stepBuilderFactory;
    @Autowired
    private SimpleJobLauncher jobLauncher;

    @Value("${batch.timeoutForm.chunk}")
    int chunk;

    @Autowired
    TimeoutFormReader reader;


    @Autowired
    TimeoutFormProcessor processor;

    @Autowired
    public TimeoutFormWriter writer;

    @Bean
    public Step createStep() {
        return stepBuilderFactory.get("timeoutFormStep").<MyFormEntity, MyFormEntity>chunk(chunk).reader(reader).processor(processor).writer(writer).build();
    }

    @Bean
    public Job createJob() {
        return jobBuilderFactory.get("timeoutFormJob").incrementer(new RunIdIncrementer()).flow(createStep()).end().build();
    }

    @Scheduled(cron = "${batch.timeoutForm.cron}")
    public void perform() throws Exception {
        JobParameters param = new JobParametersBuilder().addString("JobID", String.valueOf(System.currentTimeMillis())).toJobParameters();
        jobLauncher.run(createJob(), param);
    }
}

我的 testConfiguration 的配置

@SpringBootConfiguration
@EnableAutoConfiguration
public class TestConfig {
       public static void main(String[] args) {
           SpringApplication.run(Application.class, args);
       }
}

和测试

@RunWith(SpringJUnit4ClassRunner.class)
@DataJpaTest
public class TimeoutFormJobTest {
    @Autowired
    private JobLauncherTestUtils jobLauncher;

    @Test
    public void testIntegration_batch() throws Exception {
        assertEquals(1, myService.findFormNotfinish().size());
        jobLauncher.launchJob();
        assertEquals(0, myService.findFormNotfinish().size());
    }

}

我有错误

org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为“abcbatch.TimeoutFormJobTest”的bean时出错:通过字段“jobLauncher”表示不满足的依赖关系;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有“org.springframework.batch.test.JobLauncherTestUtils”类型的合格 bean:预计至少有 1 个有资格作为自动装配候选者的 bean。依赖注解:{@org.springframework.beans.factory.annotation.Autowired(required=true)}

我试图添加到 ConfigTest

@Autowired
DataSource dataSource;
@Autowired
PlatformTransactionManager transactionManager;

@Autowired
SimpleJobLauncher jobLaucher;
@Autowired
JobRepository jobRepository;
@Autowired
@Qualifier("timeoutFormJob")
Job job;


@Bean
public SimpleJobLauncher jobLauncher(JobRepository jobRepository) {
    SimpleJobLauncher launcher = new SimpleJobLauncher();
    launcher.setJobRepository(jobRepository);
    return launcher;
}

@Bean
public JobRepository jobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setTransactionManager(transactionManager);
    factory.afterPropertiesSet();
    return (JobRepository) factory.getObject();
}

@Bean
public JobLauncherTestUtils getJobLauncherTestUtils(){
    JobLauncherTestUtils jobLauncherTestUtils = new JobLauncherTestUtils();
    jobLauncherTestUtils.setJob(job);
    jobLauncherTestUtils.setJobRepository(jobRepository);
    jobLauncherTestUtils.setJobLauncher(jobLaucher);
    return jobLauncherTestUtils;
}

我得到了错误

>***************************
>APPLICATION FAILED TO START
>***************************
>Description:
>
>Field job in a.b.c.Application >required a bean of type 'org.springframework.batch.core.Job' that could not be >found.
>
>Action:
>Consider defining a bean of type 'org.springframework.batch.core.Job' in your >configuration

我试图改变

@Qualifier("timeoutFormJob) Job job

经过

@Autowired TimeoutFormJob jobConfig; ... jobLauncherTestUtils.setJob(jobconfig.createJob());

但我得到了

没有可用的“abcbatch.config.TimeoutFormJob”类型的合格 bean

我不明白错误。我试图完全遵循 spring 文档,但没有任何效果......我试图在 stackoverflow 上找到解决方案,但我没有找到带有批处理声明注释的示例

#### 编辑

我删除一切从零开始

我查看了 SpringBatchTest 的文档并尝试了 id 但我遇到了其他一些错误我必须添加 @EnableAutoConfiguration (即使我已经在 ConfigTest 中得到它)

我在spring doc中看到@ContextConfiguration添加作业我必须添加批处理中使用的所有读取器/处理器/写入器/服务/我的映射器......

现在看起来像

@RunWith(SpringJUnit4ClassRunner.class)
@DataJpaTest
@Sql({"classpath:org/springframework/batch/core/schema-drop-h2.sql", "classpath:org/springframework/batch/core/schema-h2.sql"})
@SpringBatchTest
@ContextConfiguration(classes = {BatchConfiguration.class, TimeoutFormJob.class, Reader.class, Processor.class, Writer.class, ServiceA.class, MapperA.class, HelperMapper.class, ServiceB.class})
@EnableAutoConfiguration
public class TestBatch {

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;
    @Autowired
    private TestEntityManager entityManager;
    @Autowired
    private MyRepo myRepo;

    @Test
    public void myBatchTest() {
        assertEquals(0, myRepo.findAll().size());
        entityManager.persist(new MyEntity());
        assertEquals(1, myRepo.findAll().size());
        JobExecution jobExecution = jobLauncherTestUtils.launchJob();
        Assert.assertEquals("COMPLETED", jobExecution.getExitStatus().getExitCode());
        assertEquals(0, myRepo.findAll().size());
    }

}

但是当 addind @ContextConfiguration 我不能再使用嵌入式数据库时......当我尝试坚持时,我得到了一个

错误:没有正在进行的交易

标签: springspring-bootspring-batchspring-testspring-boot-test

解决方案


您需要JobLauncherTestUtils在测试上下文中添加一个类型的 bean。就像是:

@Bean
public JobLauncherTestUtils jobLauncherTestUtils() {
    return new JobLauncherTestUtils();
}

For the record, Spring Batch v4.1 introduced a new annotation called @SpringBatchTest that automatically adds the JobLauncherTestUtils to your context. For more details, please refer to the Creating a Unit Test Class section of the reference documentation.

Hope this helps.


推荐阅读