방명록
- [spring] 설정 분리 (@SpringBootTest, @Profile, @ActiveProfiles, @TestPropertySource, @TestConfiguration)2024년 06월 18일 23시 57분 21초에 업로드 된 글입니다.작성자: @kimyu0218
@SpringBootTest
`@SpringBootTest`는 스프링 부트 어플리케이션의 통합 테스트를 위한 어노테이션이다. 전체 어플리케이션 컨텍스트를 로드하여 실제 어플리케이션과 동일한 환경에서 테스트를 진행할 수 있다.
`@BootstrapWith(SpringBootTestContextBootstrapper.class)`은 테스트 컨텍스트를 부트스트랩하고 어플리케이션 컨텍스트를 로드한다.
- `SpringBootTestContextBootstrapper` : `TestContextBootStrapper`를 상속하여 테스트 환경을 설정한다.
- 컨텍스트 로더로 `SpringBootContextLoader`를 사용한다.
- `@SpringBootApplication`을 사용하여 어플리케이션 컨텍스트를 초기화한다.
- 스프링 부트의 기본 설정 파일 `application.properties` 를 로드한다.
- `/config/application.properties`
- `/application.properties`
- `/src/main/resources/config/application.properties`
- `/src/main/resources/application.properties`
- 활성화된 프로파일이 있다면, 프로파일에 맞는 설정 파일 `application-[PROFILE].properties`을 추가적으로 로드한다.
- (`@SpringBootApplication`에 포함된) `@EnableAutoConfiguration` 및 `@ComponentScan`을 바탕으로 어플리케이션 컨텍스트를 초기화한다.
- `@EnableAutoConfiguration`은 자동 구성, `@ComponentScan`은 명시적 빈을 등록한다.
- 동일한 타입의 빈이 중복으로 정의되었다면, 명시적 빈이 우선한다.
🤔 명시적 빈이 우선할 수 있는 이유 : `@ConditionalOn*`
- `org.springframework.boot.autoconfigure`의 클래스에는 `@ConditionalOn*` 어노테이션이 붙어있다.
- `@ConditionalOn*`은 특정 조건을 충족할 때 빈을 생성한다.
- `@ConditionalOnBean` : 지정된 타입의 빈이 이미 컨텍스트에 존재할 때
- `@ConditionalOnMissingBean` : 지정된 타입의 빈이 컨텍스트에 존재하지 않을 때
- `@ConditionalOnClass` : 지정된 클래스가 classpath에 존재할 때
- `@ConditionalOnMissingClass` : 지정된 클래스가 classpath에 존재하지 않을 때
- `@ConditionalOnProperty` : 특정 속성의 값이 조건을 만족할 때
💡 속성
- `properties` : 테스트에 적용할 속성 지정
- 개별 key-value 등록 (ex. `spring.datasource.url=[URL]`)
- 속성 파일 위치 지정 (ex. `spring.config.location=classpath:[PROPERTY_FILE_PATH]`)
- `classes` : 테스트에 사용할 자바 기반 설정 지정 (ex. `classes = { SpringConfig.class, SpringTestConfig.class })`)
- `args` : 어플리케이션 인자 정의 (ex. `--server.port=8080`)
@Profile
`@Profile`은 특정 프로파일이 활성화되었을 때만 설정이나 빈이 컨텍스트에 등록되도록 한다. (클래스 레벨, 메서드 레벨모두 가능!) 이를 활용하여 개발, 테스트, 운영 환경에서 각각 다른 설정을 적용할 수 있다.
@Configuration @Profile("dev") public class DevConfig { ... } @Configuration @Profile("prod") public class ProdConfig { ... }
프로파일 활성화
`@ActiveProfiles`는 `org.springframework.test.context`에 속한 어노테이션으로, 테스트에서 특정 프로파일을 활성화할 때 사용한다.
@ContextConfiguration @ActiveProfiles("dev") public class DevIntegrationTest { ... } @ContextConfiguration @ActiveProfiles("prod") public class ProdIntegrationTest { ... }
💡 `org.springframework.test.context.ContextConfiguration`
- 통합 테스트 시 어플리케이션 컨텍스트를 로드하고 구성한다.
- `@ContextConfiguration(classes = SpringIntegrationTestConfig.class)`
- 스프링 부트 어플리케이션의 전체 컨텍스트를 로드하지 않기 때문에 모든 빈이 로드되지 않을 수 있다. 이 경우 `@SpringBootTest`를 사용한다.
🚨 `@ContextConfiguration`이 제대로 동작하지 않을 때 필요한 어노테이션
- `@ExtendWith(SpringExtension.class)` : JUnit 5와 스프링 테스트 컨텍스트를 통합하여 테스트에서 스프링의 기능을 사용할 수 있다. (ex. 의존성 주입)
- `@EnableAutoConfiguration` : 스프링 부트의 자동 설정을 활성화하여 classpath에 있는 설정 파일을 기반으로 스프링 빈을 자동으로 구성한다.
- `@ComponentScan` : 지정된 패키지에서 컴포넌트를 스캔하고, 어플리케이션 컨텍스트에 등록한다.
// 1. SpringBootTest ver. @SpringBootTest(classes = [JAVA_BASED_CONFIGURATION_CLASS], properties = "spring.config.location=classpath:[PROPERTY_FILE_PATH]") // 2. ContextConfiguration ver. @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = [JAVA_BASED_CONFIGURATION_CLASS]) @TestPropertySource(locations = "classpath:[PROPERTY_FILE_PATH]") @EnableAutoConfiguration @ComponentScan(basePackages = "[BASE_PACKAGE]") // 3. SpringJUnitConfig ver. @SpringJUnitConfig([JAVA_BASED_CONFIGURATION_CLASS]) @TestPropertySource(locations = "classpath:[PROPERTY_FILE_PATH]") @EnableAutoConfiguration @ComponentScan(basePackages = "[BASE_PACKAGE]")
이외에도 `*.properties` 파일을 활용하여 `@AcitveProfiles` 없이도 프로파일을 지정할 수 있다.
spring.profiles.active=dev
@TestPropertySource
특정 속성 파일이나 인라인 속성을 추가하여 테스트 환경에서 별도의 설정을 적용할 수 있도록 한다.
- 속성 파일 위치 지정 : `locations = "classpath:[PROPERTY_FILE_PATH]"`
- 인라인 속성 설정 : `properties = "[KEY]=[VALUE]"`
... @TestPropertySource(locations = "classpath:application-test.properties") class TestPropertySourceTest { ... }
@TestConfiguration
테스트 환경을 위한 추가적인 자바 기반 설정을 정의할 때 사용하는 어노테이션이다. 주로 테스트에서만 필요한 빈들을 정의하고 기존 구성 요소를 대체하기 위해 사용한다.
@TestConfiguration public class TestConfig { ... @Bean public TestBean testBean() { ... } }
💡 `@Configuration`과 유사하지만 테스트 컨텍스트에만 적용된다는 차이가 있다.
`@SpringBootTest` `@Profile` `@ActiveProfiles` `@TestPropertySource` `@TestConfiguration` boot.test.context context.annotation test.context test.context boot.test.context 클래스 레벨 클래스/메소드 레벨 클래스 레벨 클래스 레벨 클래스 레벨
참고자료
'backend > 프레임워크' 카테고리의 다른 글
[spring] 스프링 컨테이너 & 빈 (IoC/DI/라이프사이클/빈 정의/빈 스코프) (0) 2024.06.15 다음글이 없습니다.이전글이 없습니다.댓글 - `SpringBootTestContextBootstrapper` : `TestContextBootStrapper`를 상속하여 테스트 환경을 설정한다.