-
[스프링부트] 테스트 시 Mysql관련 에러 Unique index or primary key violationBackEnd/SpringBoot 2023. 11. 24. 11:27
0. 결론
1. @SpringBootTest를 사용하였고 컴포넌트스캔 범위가 전역으로 지정되었다.
2. 따라서 기존에 CommandLineRunner로 만든 더미데이터 컴포넌트를 스캔해서 데이터를 읽어서 발생한 오류였다.
3. 디버깅을 해서 쿼리 확인을 해보는게 가장 빨리 해결하는 방법인것같다.
4. 또한 통합테스트가 아니고서는 테스트 속도가 현저하게 떨어질수있기때문에 각 테스트에 맞게 테스크 클래스를 선택해야 한다.
1. 발생 경위
테스트코드 런타임중 에러 발생
에러코드 : [23505-214]
설명 : Unique index or primary key violation:
"PUBLIC.UK_GXRAOQ3YFQ2112DHX6K3I3QWO_INDEX_2 ON PUBLIC.USER_MS(USER_EMAIL NULLS FIRST) VALUES ( /* 1 */ 'test@email.com' )"; SQL statement:
풀이 : 제약조건 위반으로 발생한 문제이다.
에러가 발생한 테스트 코드는 다음과 같다.
메서드도 하나이고 BeforeEach에서 데이터를 처음 생성하는 과정이었다.
디비도 로컬디비가 아닌 메모리 디비로 테스트를 작성하는 부분이어서 데이터가 아예초기화 된 상태에서 진행되는 테스트였다고 생각했다.
메서드도 하나이고 BeforeEach에서 데이터를 처음 생성하는 과정이었다.
2. 문제원인
@SpringBootTest(통합테스트)로 진행한 테스트여서 발생한 오류였다.
Component로 생성한 더미데이터 클래스로 더미데이터의 회원 email과 테스트 코드의 email이 동일하다 (email unique키)
문제의 원인인데 @SpringBootTest를 통해서 앞선 컴포넌트를 읽었기때문에 동일한 unique로 설정된 email과 동일한 회원값이 있어서 충돌이 발생했다.
3. 해결
1. 테스트 코드와 더미데이터의 정보를 다르게 설정 - 임시방편
2. 컴포넌트스캔으로 정확한범위 테스트 범위 지정 - 통합테스트가 아닌경우는 DataJpaTest를 통해서 필요한 컨테이너만 로드
위의 SpringBootTest는 무겁기때문에 아래와 같이 특정 기능 테스트용으로 만 사용한다.
QueryDsl사용 레포지토리가 존재하기때문에 JpaQueryFactory는 별도로 테스트 빈으로 등록이 필요하다.
등록후 테스트 코드에 @Import(TestContainer.class)로 적용
@ActiveProfiles("test") // 현재 프로필 설정 @DataJpaTest(properties = "classpath:application.yaml") // 프로퍼티 로드 @ComponentScan(basePackages = { // 사용할 컨테이너들만 위치 지정 "com.trip.penguin.room", "com.trip.penguin.user", "com.trip.penguin.company", "com.trip.penguin.booking", "com.trip.penguin.review", "com.trip.penguin.recommand.room.repository", "com.trip.penguin.recommand.room.service" }) @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY) // 사용할 DB전략 @Import(TestContainer.class) // QueryDsl용 설정 컨테이너
'BackEnd > SpringBoot' 카테고리의 다른 글
[스프링부트] @DataJpaTest 멀티스레드에서 no value present (1) 2023.12.06 [스프링부트] 이미지 업로드 테스트 postman + restdocs (0) 2023.12.03 [스프링부트] ./gradlew build시 에러 -> error: cannot find symbol (0) 2023.11.16 토비의 스프링 - 1권 6장 AOP (0) 2023.10.08