Spring Batch 테스트 환경 구축(With Redis)
개요
spring-batch는 사용하지만 테스트코드는 일절없는 환경. 테스트 코드를 작성할 수 있는 환경이 필요(성능 테스트 등을 위하여)
환경: spring-boot : 2.7.4
- 의존성 추가
spring-boot-starter-test
: Junit사용 때문 spring-batch-test
: SpringBatchTest 애노테이션 사용 h2
: JobLauncher가 사용할 테스트용 데이터베이스
- 실행할 배치Job에 대한 테스트 코드 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// For Junit
@RunWith(SpringRunner.class)
@SpringBatchTest
@SpringBootTest(classes = {TestBatchConfig.class, SampleJob.class}) //Batch 설정와 테스트할 Job을 추가합니다.
@Import({TestRedisConfig.class}) // Redis 셋팅
@ActiveProfiles("test")
public class BatchSimpleTest {
@MockBean
EnvService envService;
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Test
public void 테스트코드_샘플() throws Exception {
//given
JobParameters jobParameter = new JobParametersBuilder().toJobParameters();
//when
JobExecution jobExecution = jobLauncherTestUtils.launchJob(jobParameter);
//then
Assertions.assertThat(jobExecution.getStatus()).isEqualTo(BatchStatus.COMPLETED);
}
}
여기서 별도로 작성해줘야할 클래스들은 TestBatchConfig.class
와 SampleJob.class
,TestRedisConfig
입니다.
TestBatchConfig.class의 용도는
조졸두님의 https://jojoldu.tistory.com/455 해당 글을 보는게 더 도움이 될 듯합니다.
1
2
3
4
5
6
//TestBatchConfig.class
@Configuration
@EnableAutoConfiguration
@EnableBatchProcessing
public class TestBatchConfig {
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//TestRedisConfig
public class TestRedisConfig {
@Value("${spring.redis.nodes}")
private String[] nodes;
@Value("${spring.redis.password}")
private String password;
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
ClusterServersConfig clusterServer = config.useClusterServers();
clusterServer.setScanInterval(2000);
clusterServer.addNodeAddress(nodes);
clusterServer.setReadMode(ReadMode.MASTER);
clusterServer.setPassword(password);
clusterServer.setMasterConnectionMinimumIdleSize(5);
clusterServer.setMasterConnectionPoolSize(50);
clusterServer.setSlaveConnectionMinimumIdleSize(5);
clusterServer.setSlaveConnectionPoolSize(50);
config.setCodec(OcJsonJacksonCodec.INSTANCE);
return Redisson.create(config);
}
}
회사 기준 서버 구성이라 Redis가 클러스터링되어있습니다. 각자 환경에 맞게 코드를 수정하면 될 것 같습니다. 이 부분은 각자 환경에 따라 구성이 달라질 것이라 따로 설명 드리지는 않겠습니다.
SampleJob.class
의 경우에는 실제 사용할 Job을 넣지만 저는 테스트용으로 하나 만들어서 넣었습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Slf4j
@TestConfiguration
public class SampleJob {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean(name = "testSampleJob")
public Job sampleJob() {
return jobBuilderFactory.get("sampleJobTest")
.incrementer(new RunIdIncrementer())
.start(sampleStep())
.build();
}
@Bean
public Step sampleStep() {
int i = 0;
return stepBuilderFactory.get("sampleStepTest")
.<Integer, String>chunk(200)
.reader(new ItemReader<Integer>() {
private int count = 0;
@Override
public Integer read() {
count++;
if (count < 500) {
return i;
} else {
return null;
}
}
})
.writer(items -> log.info(" >>> {}", items.size()))
.build();
}
}
해당 Job은 200개씩 데이터를 읽고 500개째에서 Job을 종료하는 간단한 로직입니다.
- 실행할 배치에 대한 Profile 작성
다른 Profile로 테스트를 돌리면 알 수 없는데서 충돌이 나거나 오류가 날 수 있으므로 따로 Profile(@ActiveProfiles(“test”))을 적용하였습니다.
따라서 이에 맞춘 설정 값들을 적용시켜줘야합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# application-test.yml
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password:
redis:
nodes:
password:
h2:
console:
enabled: true
logging:
level:
root: INFO
config: classpath:logback-test.xml
여기서 또한 log에대한 설정도 따로 지정해줬기에 같은 test/resources에 logback-test.xml을 작성해줍니다.
1
2
3
4
5
6
7
8
9
10
11
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
자, 이제 통합테스트를 위한 구성은 모두 마무리되었습니다.
이제 테스트코드를 실행해서 확인해봅니다.
성공하였습니다.
저는 회사의 모종의 이유를 레디스를 직접 붙어서 사용하게 되었는데, Mocking을 하거나 테스트용 컨테이너 레디스를 올려서 진행해도 되니 참고하면 될 것 같습니다.