0. 들어가기 전
이번에 테스트를 만들다가, @Sql문으로 초기 스키마와 데이터를 넣게 되었다.
그런데 테스트를 실행해보니 중복 데이터가 있다는 오류가 발생하게 됐다.
결론적으로, main 디렉토리 아래에 있는 초기화 sql을 실행하고 나서,
@Sql의 초기 스키마와 데이터 sql을 실행해서 발생한 문제였다.
Trouble Shooting 과정을 기록하고자 한다!
1. 문제 상황
기존의 sql 파일 구조는 위와 같았다.
src/main/resources 아래에 프로덕션용 schema.sql, data.sql이 존재했고,
src/test/resources 아래에 테스트용 test-schema.sql, test-data.sql이 존재했다.
이 상황에서 아래와 같은 테스트를 실행하니 오류가 발생했다.
@JdbcTest
@Sql({"/test-schema.sql", "/test-data.sql"})
class MemberDaoTest {
@Autowired
private JdbcTemplate jdbcTemplate;
private MemberDao memberDao;
@BeforeEach
void setUp() {
this.memberDao = new MemberDao(jdbcTemplate);
}
...
}
2. 문제 원인
문제의 원인은 다음과 같았다.
스프링부트는 기본적으로 classpath 아래의 리소스 파일이 우선순위를 가진다.
classpath는 기본적으로 프로덕션 환경, 테스트 환경에서 다음과 같이 다르다.
1. 프로덕션 환경 Classpath : src/main/resources
2. 테스트 환경 Classpath : src/test/resources
내가 테스트 DB 초기화를 할 때는 테스트 환경이므로 src/test/resources에 초기화 sql이 없으면 초기화가 안 될줄 알았다.
그런데, 실제로는 src/main/resources의 초기화 sql을 실행해서 오류가 발생한 것이었다.
테스트 환경의 Classpath에 리소스 파일이 존재하지 않으면, 프로덕션 환경의 Classpath의 리소스 파일을 실행시킨다.
이 부분을 모르고 당연히 테스트 Classpath에 초기화가 되지 않으므로, @Sql로 초기화를 해주었는데
이미 프로덕션 환경 Classpath의 초기화 Sql을 실행해서 이중 초기화가 되어 오류가 발생한 것이다!
※ 단, 실제 프로덕션 환경의 스프링 Application을 실행하는 @SpringBootTest의 RANDOM_PORT로 실행하면,
src/test/resources 디렉토리가 아닌 src/main/resources를 읽게 된다!
3. 문제 해결
간단하게 테스트 환경의 초기화 SQL을 schema.sql, data.sql로 만들어서 초기화되도록 fix했다.
'Spring' 카테고리의 다른 글
[Spring] 스프링 동시성 처리 방법(feat. 비관적 락, 낙관적 락, 네임드 락) (4) | 2023.11.21 |
---|---|
[Spring] SpringBoot의 Tomcat 설정 알아보기 (feat. Thread, Thread Pool) (4) | 2023.09.14 |
[Spring] 스프링 이벤트를 사용하여 도메인 의존성 분리하기 (2) | 2023.07.30 |
[Spring] 스프링 HTTP API 요청 & 응답 시 역직렬화 직렬화 원리 (4) | 2023.04.18 |
[Spring] Spring Boot application.yml 환경별 프로필 설정 방법 (SpringBoot 2.4 기준 비교) (2) | 2022.08.28 |