java - 如何在不运行整个作业的情况下测试 Spring Batch 步骤

标签 java spring unit-testing junit spring-batch

我正在开发一个 Spring Batch 应用程序,该应用程序在一个作业中有两个步骤。我正在尝试单独测试每个步骤。根据 Spring 文档,我应该能够使用 JobLauncherTestUitls.launchStep() 我为其中一个步骤设置了以下测试

@SpringBootTest
@SpringBatchTest
@EnableAutoConfiguration
@ContextConfiguration(classes = {JobConfig.class, EmailAndArchiveStepConfig.class, UpdateFactorReserveConfig.class})
@ExtendWith(SpringExtension.class)
@ActiveProfiles("test")
class ConfigTest {

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    private JdbcTemplate jdbcTemplate;

    @Autowired
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    @Test
    @DisplayName("Testing Email and Archive Configured")
    public void testEmailAndArchiveConfig(){
        JobExecution jobExecution = jobLauncherTestUtils.launchStep("Email and Archive", executionContext);

        assertEquals(new ExitStatus("COMPLETED").getExitCode() ,jobExecution.getExitStatus().getExitCode());
    }

但是,当我运行这个测试时,它会从头开始作业,同时运行另一个步骤,而不是只运行我要测试的这个步骤。我还没有找到任何解决方案。

最佳答案

您可能看到的是,当您运行测试时,Spring Boot 默认运行您的作业。您可以通过将 spring.batch.job.enabled=false 添加到您的测试属性来禁用它。

使用 jobLauncherTestUtils.launchStep 应该只启动步骤而不是整个作业,这里是快速的独立示例:

import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import static org.junit.Assert.assertEquals;

@SpringBatchTest
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = ConfigTest.JobConfig.class)
public class ConfigTest {

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    @Test
    public void testStep1() {
        JobExecution jobExecution = jobLauncherTestUtils.launchStep("step1");
        assertEquals(new ExitStatus("COMPLETED").getExitCode() ,jobExecution.getExitStatus().getExitCode());
    }

    @Configuration
    @EnableBatchProcessing
    public static class JobConfig {

        @Bean
        public Step step1(StepBuilderFactory stepBuilderFactory) {
            return stepBuilderFactory.get("step1")
                    .tasklet((contribution, chunkContext) -> {
                        System.out.println("hello");
                        return RepeatStatus.FINISHED;
                    })
                    .build();
        }

        @Bean
        public Step step2(StepBuilderFactory stepBuilderFactory) {
            return stepBuilderFactory.get("step2")
                    .tasklet((contribution, chunkContext) -> {
                        System.out.println("world");
                        return RepeatStatus.FINISHED;
                    })
                    .build();
        }

        @Bean
        public Job job(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory) {
            return jobBuilderFactory.get("job")
                    .start(step1(stepBuilderFactory))
                    .next(step2(stepBuilderFactory))
                    .build();
        }

        @Bean
        public DataSource dataSource() {
            return new EmbeddedDatabaseBuilder()
                    .setType(EmbeddedDatabaseType.HSQL)
                    .addScript("/org/springframework/batch/core/schema-hsqldb.sql")
                    .build();
        }

    }
}

此测试打印 hello,这意味着它只启动了 step1 而不是整个作业。此示例未使用 Spring Boot 并按预期工作,我相信这证实了您看到的行为与 Spring Boot 自动执行作业有关。

关于java - 如何在不运行整个作业的情况下测试 Spring Batch 步骤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68117720/

相关文章:

java - 计划线程池完成后更改 JButton 的文本

unit-testing - 在 espresso 测试中检查按钮是否可点击,android studio

java - jar 的最佳去处

java - HQL 中的日期限制

java - 数组索引越界,使用多维数组作为游戏板

c++ - 使用 C/C++ : Lessons, 进行单元测试要记住什么?

python - 如何使覆盖范围包括未测试的文件?

spring - 注册过滤器时 "addMappingForServletNames()"的含义是什么?

java - Spring 中的属性,在 Java 应用程序中访问

spring - 如何将 MessageSource 注入(inject)到扩展 AbstractView 的 View 中