简体   繁体   中英

How to test Spring Batch step without running entire job

I am working on a Spring Batch application that has two steps in a job. I am trying to test each step individually. According to Spring documentation, I should be able to do so using JobLauncherTestUitls.launchStep() I have the following test set up for one of the steps

@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());
    }

However, when I run this test, it starts the job from the beginning, running the other step as well, rather than just running this step that I want to test. I have not been able to find any solution to this.

What you are probably seeing is the fact that Spring Boot is running your job by default when you run your test. You can disable that by adding the spring.batch.job.enabled=false to your test properties.

Using jobLauncherTestUtils.launchStep should only launch the step and not the entire job, here is quick self-contained example:

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();
        }

    }
}

This test prints hello which means it only launched step1 and not the entire job. This example does not use Spring Boot and works as expected, which I believe confirms that the behaviour you are seeing is related to the automatic execution of jobs by Spring Boot.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM