[springboot] Test code: profile and configuration
환경: springboot3, java17
소스를 배포 환경(ex. dev, stage, real...)에 따라 실행할 때 보통 profile 옵션을 줘서 환경에 맞는 프로퍼티 파일을 들고 갈 수 있게 한다.
$JAVA11_PATH/java -jar -DappName=$APP_NAME -Dspring.profiles.active=$ACTIVE_PROFILE $DEPLOY_DIR/$JAR_NAME 1>/dev/null 2>/dev/null &
테스트 코드를 짤 때 필요한 설정파일은 보통 test/resources패키지 안에 application.yml로 만든다.
문득 궁금한 게 어떨 때는 test/resources/application-test.yml로 만들고 어떨 때는 test/resources/application.yml로 만들었던 것 같다.
두 개가 같은 상황으로 인식되나? 궁금해서 파헤쳐 본다.
테스트 코드를 위한 프로퍼티 파일
1. test/resources/application.yml로 만들면
테스트가 돌아갈 때 기본적으로 들고 가며 main/resources/application.yml을 덮어쓰는 효과가 난다.
테스트 코드에 아무 설정을 하지 않아도 적용된다.
2. test/resources/application-test.yml로 만들면
테스트 폴더 안에 있지만 어쨌건 profile이 적용된 파일이라 프로파일을 적용해야만 반영된다.
적용하는 방법은 아래처럼 소스에다 명시한다(모든 소스에다 다 해야 하면 1번 방법을 쓰는 게 낫다.)
@ActiveProfiles("test") // test profile을 적용하라는 뜻
@Import({TestBatchConfig.class})
@SpringBootTest
class DailyRankingJobConfigTest {
혹은 외부에서 주입해야 한다.(위에 jar 실행 시처럼)
반대로 해당 빈을 특정 프로파일(ex. test)에서만 사용해야 한다면
1. 빈으로 프로파일을 명시한다.
@Profile("test")
@Configuration
위 설정은 profile=test 일 때만 로드된다.
2. 테스트에서만 사용하는 설정의 경우
프로파일에 상관없이 테스트에서만 사용된다면 아래 어노테이션을 사용하면 된다.
@TestConfiguration
사용 예제
즉, 테스트 코드에서 아래 어노테이션을 사용한다면..
@ActiveProfiles("test")
1. 테스트 코드에서 2. 테스트 프로파일을 불러오는 것이므로
@Profile("test")
@Configuration
가 달린 설정과
@TestConfiguration
가 달린 설정 모두를 불러오게 된다.
추가적으로 궁금한 사항.....
@TestConfiguration
public class TestBatchConfig {
@Bean
public JobTestUtils jobTestUtils(){
해당 파일은 테스트 코드가 돌 때 자동으로 빈으로 등록하는 것인데
@ActiveProfiles("test") // test profile을 적용하라는 뜻
@ContextConfiguration(classes = {TestBatchConfig.class}) //or @Import({TestBatchConfig.class})
@SpringBootTest
class DailyRankingJobConfigTest {
@Autowired private JobTestUtils jobTestUtils;
정작 테스트 코드에서 두 번째 줄을 지우면 JobTestUtils 빈을 못 찾아서 테스트가 실패한다. 아니 테스트 코드 설정이라면서 왜정작 못 불러오는 거지..
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'DailyRankingJobConfigTest'
: Unsatisfied dependency expressed through field 'jobTestUtils': No qualifying bean of type 'JobTestUtils' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:
관련하여 spring공식 문서를 보니 아래와 같은 부분이 있다.
정리하면, 일반 클래스(top-level)로 configuration클래스를 만들면 스캐닝되지 않고 inner class에 static으로 만들어야지만 된다는 것...?!
Testing Spring Boot Applications :: Spring Boot
To test whether Spring MVC controllers are working as expected, use the @WebMvcTest annotation. @WebMvcTest auto-configures the Spring MVC infrastructure and limits scanned beans to @Controller, @ControllerAdvice, @JsonComponent, Converter, GenericConverte
docs.spring.io
그래서 아래처럼 inner class로 만들어보니 진짜 된다..! 이럴 수가
@ActiveProfiles("test")
@SpringBootTest
class DailyRankingJobConfigTest {
@Autowired private JobTestUtils jobTestUtils;
...
@TestConfiguration
public static class TestBatchConfig {
@Bean
public JobTestUtils jobTestUtils() {
return new JobTestUtils();
}
}
}
하지만 매번 inner class로 넣을 수도 없어서 그냥 Import구문을 넣어야겠다..