일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- ObjectMapper
- FCM
- ExceptionResolver
- 자바
- JPQL
- MySQL
- mapstruct
- softeer
- Test code
- JPA
- Server
- Java
- 테크쇼
- 인프콘2023
- 소프티어
- modelmapper
- Test
- enumSet
- OS
- Junit 5
- 공룡책
- db
- RequestBody
- Spring
- proxyFactory
- 일상
- Coputer Science
- backend
- Service 계층 테스트
- Test Doulbe
- Today
- Total
공부내용공유
Test Code H2 DB 사용시 주의사항 본문
서론
Repository 계층 테스트 코드를 작성할때 처음에는 어플리케이션에서 사용중인 MySQL DB를 그대로 사용하였다.
그러다가 한 테스트에서 로컬에 저장되어 있던 데이터에 의해 테스트가 실패하였고, 물론 값을 바꿔주면 테스트를 통과하긴 하겠으나 이 테스트가 다른 사람 pc에서 안깨지려면 테스트 DB를 분리하는게 맞겠다는 생각이 들었다.
Spring 으로 프로젝트를 진행할때 local DB 나 Test DB 로 H2 를 많이 사용하기에 나도 H2 DB 로 설정을 바꿔주고 테스트를 돌렸다.
그런데 잘만 돌아가던 테스트들이 깨지는 케이스가 발생했다. 이를 기억하고 앞으로 코드를 작성할때 주의해야겠다는 생각이 들어 이 글을 작성하였다.
본론
테스트가 깨진 경우는 2가지 였다.
- native query 사용으로 인한 MySQL ↔ H2 간 Syntax Error
- H2 에서는 user 가 예약어라 table 생성 불가
Native Query 사용
이 문제는 나의 JPQL 이해도 부족으로 생긴 문제이다.
로직중에 scheduling 을 하여 날짜가 지난 강의들의 상태를 업데이트 하는게 있다.
강의에 강의 날짜들이 List 형태로 있고 그 날짜중 가장 마지막 날짜와 오늘 날짜를 비교해 같을 경우 강의 상태를 finished 로 바꾸는 로직이다.
처음에 JPQL 을 사용하여 코드를 작성할때 그래프 탐색을 통해 lecture → lectureDates → 날짜
이런식으로 값을 가지고 쿼리를 짜려 했는데 lectureDates 에서 더이상 탐색이 되지 않았다.
Native Query 로는 작성하는 법을 알겠는데 JPQL 로는 작성이 안되는 상태였고 빠르게 추가하고 테스트 해봐야 했던 로직이라 일단 native query 로 구현하였었다.
query 의 일부분중 문제가 생긴 파트다.
"group by ld.lecture_id having date_format(max(lecture_dates),\\"%Y-%m-%d\\") = date_format(:finishedDate,\\"%Y-%m-%d\\")) "
,nativeQuery = true)
MySQL 로 테스트를 돌릴때는 정상적으로 잘 돌아갔다. 그런데 H2 DB 로 바꾸자마자 Syntax Error 가 발생하였다.
date_format 이 h2 에서는 다른 방언으로 사용되었던 것이다.
Function "DATE_FORMAT" not found; SQL statement:
native query 여서 JPA 측에서 제공하는 방언변환도 되지 않았고 결국 syntax error 가 발생하였다.
그래서 나중에 JPQL 에 대해 좀 더 알아보면서 값타입 컬렉션의 경우 from 에서 명시적 조인을 하면 크래프 탐색이 된다는것을 알게되고 해당 query 문을 JPQL 로 작성하였고 테스트도 정상적으로 돌아가게 되었다.
이번 경험을 통해 native query 를 함부로 사용하면 안되겠다는 생각이 들었다.
물론 JPQL 의 한계상 복잡한 쿼리는 native query 로 작성하는 상황이 생기겠지만 이때도 최대한 DB 에 종속적인 문법을 피하면서 짜거나 차라리 몇개의 쿼리로 나누는게 낫지 않을까 싶다.
User 예약어
이는 문제도 명확했고 해결책도 명확했다.
MySQL 에서 H2 로 바꾸자마자 userRepository.save (user) 에서 오류가 났다.
Syntax error in SQL statement "insert into [*]user
로직을 전혀 바꾼거도 없고 column 값들도 전부 잘 넣어줘서 뭔가 했는데 구글에 검색해보니 DB 예약어를 사용했을때 이러한 오류가 발생한다는걸 알게되었다.
그래서 뭔가 싸하다 싶은 column 들을 H2 예약어인지 확인하면서 실행시켜봤는데 문제는 바로 user 테이블이였다.
H2 DB 에서는 User 가 예약어라 Table 이름을 보통 Users 로 한다고 하여 users 로 바꿔주니 바로 해결 되었다.
결론
엄청 큰 문제들은 아니였지만 나름 알아보면서 얻은거도 많고 기억하고 있으면 좋을거 같아 정리를 간단히 하였다.
JPQL 에 대해 한번 쭉 정독하면서 복습하고, 다음 프로젝트에서는 DB 예약어 등들을 미리 어느정도 파악하고 Table 이름을 설정해줘야겠다.
앞으로 프로젝트를 진행하면서 또 문제가 생기면 이 글에 추가할 예정이다!
'Spring > Spring' 카테고리의 다른 글
FCM 기능 구현 및 리팩토링을 하면서의 고민들 (0) | 2023.09.08 |
---|---|
Spring Proxy Factory 뜯어보기 (0) | 2023.09.05 |
Junit 5 Service,Mapstruct, ModelMapper Unit Test (단위 테스트) (0) | 2023.07.07 |
Spring ModelMapper, MapStruct 적용에 관하여 (2) | 2023.06.01 |
Test Double이란? (0) | 2023.05.20 |