[SpringBatch 실습] 34. 스프링 배치 Test 코드 작성

반응형
728x90
반응형

@SpringBatchTest

자동으로 ApplicationContext에 테스트에 필요한 여러 유틸 Bean을 등록해주는 어노테이션

클래스 설명
JobLauncherTestUtils launcJob(), launchStep()과 같은 스프링 배치 테스트에 필요한 유틸성 메서드를 지원한다.
JobRepositoryTestUtils JobRepository를 사용해서 JobExecution을 생성 및 삭제 기능 메서드를 지원한다.
StepScopeTestExecutionListener @StepScope 컨텍스트를 생성해준다.
해당 컨텍스트를 통해 JobParameter 등을 단위 테스트에서 DI 받을 수 있다.
JobScopeTestExecutionListener @JobScope 컨텍스트를 생성해준다.
해당 컨텍스트를 통해 JobParameter 등을 단위 테스트에서 DI 받을 수 있다.

 

 

테스트 코드 작성 예제

build.gradle 추가
testImplementation 'org.springframework.batch:spring-batch-test'

 

SimpleJobTest.java
@RunWith(SpringRunner.class)
@SpringBatchTest
@SpringBootTest(classes = {JobScope_StepScope_Configuration.class, TestBatchConfig.class}) // 1개만 지정
public class SimpleJobTest {

1) @SpringBatchTest

JobLauncherTestUtils, JobRepositoryTestUtils 등을 제공하는 어노테이션이다.

 

2) @SpringBootTest

Job 설정 클래스를 지정한다.

JobScope_StepScope_Configuration.class 

통합 테스트를 위한 여러 의존성 빈들을 주입 받기 위한 어노테이션이다.

 

TestBatchConfig.java
@Configuration
@EnableAutoConfiguration
@EnableBatchProcessing
public class TestBatchConfig {

}

1) @EnableBatchProcessing

테스트시 배치환경 및 설정 초기화를 자동 구동하기 위한 어노테이션이다.

 

2) @Configuration

테스트 클래스마다 선언하지 않고 공통으로 사용하기 위해서 생성한 클래스다.

 

 

JobScope_StepScope_Configuration.java
package com.project.springbatch._36_jobScope;

import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.*;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.JobScope;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/*
--job.name=jobScopeStepScopeJob
 */
@RequiredArgsConstructor
@Configuration // 빈 생성을 위해
public class JobScope_StepScope_Configuration {

    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job jobScopeStepScopeJob() {
        return this.jobBuilderFactory.get("jobScopeStepScopeJob")
                /* step start */
                .start(jobScopeStepScopeStep1(null))
                .next(jobScopeStepScopeStep2())
                .listener(new JobExecutionListener() {
                    @Override
                    public void beforeJob(JobExecution jobExecution) {
                        jobExecution.getExecutionContext().putString("name", "user1");
                    }

                    @Override
                    public void afterJob(JobExecution jobExecution) {

                    }
                })
                .build();
    }

    @Bean
    @JobScope
    public Step jobScopeStepScopeStep1(@Value("#{jobParameters['message']}") String message) {
        System.out.println("message = " + message);

        return stepBuilderFactory.get("jobScopeStepScopeStep1")
                .tasklet(tasklet1(null))
                .listener(new StepExecutionListener() {
                    @Override
                    public void beforeStep(StepExecution stepExecution) {
                        stepExecution.getExecutionContext().putString("name2",  "user");
                    }

                    @Override
                    public ExitStatus afterStep(StepExecution stepExecution) {
                        return null;
                    }
                })
                .build();
    }

    @StepScope
    public Tasklet tasklet1(@Value("#{jobExecutionContext['name']}") String name) { // 런타임에 참조 가능
        System.out.println("name = " + name); // .putString("name", "user1");

        return (stepContribution, chunkContext) -> {
            System.out.println("tasklet1 has executed");
            return RepeatStatus.FINISHED;
        };
    }

    @Bean
    public Step jobScopeStepScopeStep2() {
        return stepBuilderFactory.get("jobScopeStepScopeStep2")
                .tasklet(tasklet2(null))
                .build();
    }

    @StepScope
    public Tasklet tasklet2(@Value("#{stepExecutionContext['name2']}") String name2) {
        System.out.println("name2 = " + name2); // .putString("name2",  "user");

        return (stepContribution, chunkContext) -> {
            System.out.println("tasklet1 has executed");
            return RepeatStatus.FINISHED;
        };
    }
}

 

SimpleJobTest.java
package com.project.springbatch;

import com.project.springbatch._36_jobScope.JobScope_StepScope_Configuration;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.*;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBatchTest
@SpringBootTest(classes = {JobScope_StepScope_Configuration.class, TestBatchConfig.class}) // 1개만 지정
public class SimpleJobTest {
    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils; // launchJob, laucnStep()과 같은 스프링 배치 테스트에 필요한 유틸성 메서드 지원

    @Test
    public void simpleJob_test() throws Exception {
        // given
        JobParameters jobParameters = new JobParametersBuilder()
                .addString("message", "test seohae batch job")
                .toJobParameters();

        // when
        JobExecution jobExecution = jobLauncherTestUtils.launchJob(jobParameters);

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

    @Test
    public void simpleStep_test() throws Exception {
        // given
        JobParameters jobParameters = new JobParametersBuilder()
                .addString("message", "test seohae batch job step")
                .toJobParameters();

        /** step 1개만 테스트 */
        JobExecution jobExecution2 = jobLauncherTestUtils.launchStep("jobScopeStepScopeStep2");

        // stepExecution 꺼내기
        StepExecution stepExecution = (StepExecution) ((List) jobExecution2.getStepExecutions()).get(0);

        Assert.assertEquals(stepExecution.getStatus(), BatchStatus.COMPLETED);
        Assert.assertEquals(stepExecution.getExitStatus(), ExitStatus.COMPLETED);
    }
}

1) Job 테스트

@Test
public void simpleJob_test() throws Exception {
    // given
    JobParameters jobParameters = new JobParametersBuilder()
            .addString("message", "test seohae batch job")
            .toJobParameters();

    // when
    JobExecution jobExecution = jobLauncherTestUtils.launchJob(jobParameters);

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

▶ 파라미터 셋팅

JobParameters jobParameters = new JobParametersBuilder()
        .addString("message", "test seohae batch job")
        .toJobParameters();

 

 Job 수행 후 JobExecution 받기

수행할 Job : 클래스명 위 @SpringBootTest 에 지정된 JobScope_StepScope_Configuration.java

JobExecution jobExecution = jobLauncherTestUtils.launchJob(jobParameters);

 

 then 처리 (수행 검증)

Assert.assertEquals(jobExecution.getStatus(), BatchStatus.COMPLETED);
Assert.assertEquals(jobExecution.getExitStatus(), ExitStatus.COMPLETED);

 

2) Step 테스트

@Test
public void simpleStep_test() throws Exception {
    // given
    JobParameters jobParameters = new JobParametersBuilder()
            .addString("message", "test seohae batch job step")
            .toJobParameters();

    /** step 1개만 테스트 */
    JobExecution jobExecution2 = jobLauncherTestUtils.launchStep("jobScopeStepScopeStep2");

    // stepExecution 꺼내기
    StepExecution stepExecution = (StepExecution) ((List) jobExecution2.getStepExecutions()).get(0);

    Assert.assertEquals(stepExecution.getStatus(), BatchStatus.COMPLETED);
    Assert.assertEquals(stepExecution.getExitStatus(), ExitStatus.COMPLETED);
}

 파라미터 셋팅

JobParameters jobParameters = new JobParametersBuilder()
        .addString("message", "test seohae batch job step")
        .toJobParameters();

 

▶  Step 수행 후 StepExecution 받기

수행할 Step명 : jobScopeStepScopeStep2

/** step 1개만 테스트 */
        JobExecution jobExecution2 = jobLauncherTestUtils.launchStep("jobScopeStepScopeStep2");

        // stepExecution 꺼내기
        StepExecution stepExecution = (StepExecution) ((List) jobExecution2.getStepExecutions()).get(0);

 

 then 처리 (수행 검증)

Assert.assertEquals(stepExecution.getStatus(), BatchStatus.COMPLETED);
Assert.assertEquals(stepExecution.getExitStatus(), ExitStatus.COMPLETED);

 

 

반응형

Designed by JB FACTORY