Batch Test Code 작성

최준호·2022년 1월 19일
0

Spring Batch

목록 보기
8/10

👉 Test Code 세팅

지금 프로젝트에 세팅에 맞게만 설명하려고 한다.

먼저 기존의 SuccessStateJobTest.java 파일을 가지고 테스트 코드를 작성하고자 한다.

@ExtendWith(SpringExtension.class)  //(0) Spring framework에 junit test를 확장하여 실행하도록 선언
@SpringBatchTest    //(1) batch에 필요한 jobLauncherTestUtils, jobRepositoryTestUtils 등의 DI 적용
@SpringBootTest(classes = {TestBatchConfig.class, SuccessStateJob.class, PayRepository.class})  //(2) Spring을 시작시키며 Test를 실행하는데 classes 옵션으로 해당 테스트가 진행될때 applicationContext에 등록할 class들을 정의함. > 여기에 작성하지 않으면 테스트 실행시 DI가 되지 않아 class를 찾을 수 없다고 나옴
class SuccessStateJobTest {

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;  //(3) batch test용 library

    @Autowired
    private JobRepositoryTestUtils jobRepositoryTestUtils;  //(4) 3과 동일

    @Autowired
    private PayRepository payRepository;    //(5) 개인적으로 정의한 repository

    @Test
    void 테스트1() throws Exception{

        JobExecution jobExecution = jobLauncherTestUtils.launchJob();

        assertThat(jobExecution.getStatus()).isEqualTo(BatchStatus.COMPLETED);
    }

    @Test
    void 같은조건을읽고_업데이트() throws Exception{
        //given
        for(long i=0; i<50; i++){
            payRepository.save(new Pay(1000L, "테스트상품",LocalDateTime.now().toString(),"false")); //(6) 상품 50개 등록
        }
        //when
        JobExecution jobExecution = jobLauncherTestUtils.launchJob();   //(7) job 실행
        //then
        assertThat(payRepository.findAllByState().size()).isEqualTo(54);    //(8) 결과 확인
    }
}
  1. test를 실행하기 위해 Spring에 Test Framework를 확장적으로 선언해주는 역할
  2. batch를 실행하기 위해 필요한 DI를 쉽게 적용
  3. Spring을 시작시키며 Test를 실행하는데 classes 옵션으로 해당 테스트가 진행될때 applicationContext에 등록할 class들을 정의함. > 여기에 작성하지 않으면 테스트 실행시 DI가 되지 않아 class를 찾을 수 없다고 나옴
    • 이 중 TestBatchConfig.class는 직접 batch에 대한 설정파일로 사용자가 따로 정의해주어야한다. 글 밑에서 작성할 예정
  4. batch test 용 libarary
  5. 3과 동일
  6. 개인적으로 지정한 repository
  7. test를 위한 데이터
  8. job 실행
    • 이때 어떠한 parameter가 넣고 싶다면 JobParameter를 통해 선언하면 됨
    • 여기서 내가 어떤 job을 실행하려 하는지는 job class를 @SpringBootTest를 통해 따로 선언해놨기 때문에 선언 해놓은 여러 Job중에 내가 포함시켜둔 job class만 실행됨. 만약 포함시켜두지 않거나 여러 job을 동시에 선언해두면 여러 job이 bean으로 등록되어 찾을 수 없다고 나옴.
  9. 실행 결과 확인

👉 TestBatchConfig.java 생성(이름 상관 없음)

@Configuration
@EnableAutoConfiguration
@EnableBatchProcessing	//batch 실행시 필요한 DI
public class TestBatchConfig {
}

위에서 테스트에 포함시킨 TestBatchConfig.class test config 파일은 위와 같이 선언된다. 이전에는 JobLauncherTestUtils를 사용하기 위해 bean으로 등록해주는 코드가 필요했으나 @SpringBatchTest 어노테이션을 통해 모두 실행해주므로 Batch 실행에 필요한 설정만 해주면 된다.

👉 Repository 작성

jpa로 작성해서 사용해도 좋겠지만... 프로젝트 특성상 jdbc로 작성해야할 경우가 있다. jpa로 작성하는 방법은 향로님 batch 가이드만 따라가도 충분히 할수 있기 때문에 jdbc로 작성하는 방법을 적어두려고 한다.

✍ Repository 생성

@Repository
@RequiredArgsConstructor
public class PayRepository {
    private final JdbcTemplate jdbc;

    public List<Pay> findAll(){
        String sql = "select * from pay";
        return jdbc.query(sql, rowMapper);
    }
    public List<Pay> findAllByState(){
        String sql = "select * from pay where success_state = 'true'";
        return jdbc.query(sql, rowMapper);
    }

    public int save(Pay pay){
        return jdbc.update("insert into pay (amount, tx_name, tx_date_time, success_state) values (?,?,?,?)", pay.getAmount(), pay.getTxName(), pay.getTxDateTime(), pay.getSuccessState());
    }

    static RowMapper<Pay> rowMapper = (rs, rowNum) -> new Pay(
            rs.getLong("id"),
            rs.getLong("amount"),
            rs.getString("tx_name"),
            rs.getString("tx_date_time"),
            rs.getString("success_state")
    );

}

jdbc는 JdbcTemplate을 주입받아서 사용하면 위와 같이 간편하게 사용이 가능하다. 여기서 jpa나 mybatis를 사용하면 자동으로 dao나 entity에 맞춰서 객체로 변환해주던 작업을 우리가 직접 해줘야한다.

그래서 RowMapper를 통해 각 컬럼 값을 우리가 선언한 객체에 맞게 값을 넣어주면 생성자를 통해 객체를 생성한다.

findAll(), findBy**(), save() 정도의 예제면 충분히 활용해서 다른 코드를 짤 수 있을것이다.

직접적으로 job에서 실행되는 코드는 아니고 테스트를 위한 코드이므로 테스트 코드를 작성하지 않을 거라면 따로 작성할 필요는 없다.

batch는 따로 DB에 transaction을 통해 테스트만하고 데이터를 날려버릴 수 없다. 이 점을 기억하고 테스트할때 잘 작성하자!

향로님 batch 가이드

batch 다중 DB 세팅

profile
해당 주소로 이전하였습니다. 감사합니다. https://ililil9482.tistory.com

0개의 댓글