spring + jpa test용 db 분리

Kim yohan·2024년 1월 27일
0

TIL

목록 보기
13/16

Spring 3.1.5 + Jpa + MySQL 환경에서 토이프로젝트를 진행 중인데, 프로덕트 db의 데이터 때문에 test가 제대로 되지 않아서 test용 db 분리의 필요성을 느꼈다.

그래서 h2를 test용 db로 사용하기로 결정했다.
test용 db 분리를 하면서 겪은 시행착오들과 해결 방법들을 적어보고자 한다.
3일 동안 고통받고 겨우 해결했다.

해결 방법

1. build.gradle 설정

runtimeOnly 'com.h2database:h2' 추가

2. test resources에 application.yml 추가

test 폴더 내 resources에 설정 파일 application.yml을 추가해준다.

          spring:
            datasource:
              url: jdbc:h2:mem:testdb;MODE=MYSQL;
              username: sa
              password:
              driver-class-name: org.h2.Driver
            jpa:
              hibernate:
                ddl-auto: create
              properties:
                hibernate:
                format_sql: true
            
          logging:
            level:
              org.hibernate.SQL: debug
  • 설명
    • url
      • jdbc:h2:mem:{db이름}으로 In-Memory mode로 사용했다.
        Spring Boot 2.1.10 이후로 MODE=MYSQL를 써줘야 MySQL을 인식한다.
      • Server mode로 사용하고 싶으면, jdbc:h2:tcp://localhost/~/{db이름}으로 작성한다.

3. DB를 사용하는 test class에 어노테이션 추가

db를 사용하는 test class에 @AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)를 붙여줌

설정시, 테스트용 클래스에서 사용할 데이터베이스를 적용되게 하는 Annotation이다.

@SpringBootTest
@Transactional
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
class ImageRepositoryTest {

    @Autowired
    ImageRepository imageRepository;

    @Test
    void save() {
        Image image = Image.builder()
                .build();
        imageRepository.save(image);

        Image findImage = imageRepository.find(image.getId());

        assertThat(findImage).isEqualTo(image);
    }

시행착오

1. 유저 엔티티 예약어 문제

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "insert into [*]user.. 발생

살펴 보니 User Entity와 관련된 test들 모두 fail 났음

원인 : H2 데이터베이스 2.1.214 버전에서 user 키워드가 예약어로 지정되어 있어서 발생한 문제
해결 : User Entitiy에 @Table(name = "users") 써줘서 해결

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Entity
@Table(name = "users")
public class User {
...
}

2. MySQL5InnoDBDialect 사용시 에러

application.yml에서 dialect: org.hibernate.dialect.MySQL5InnoDBDialect 사용시 에러 발생함

원인 & 해결 : MySQL5InnoDBDialectdeprecated되었고, 따라서 MySQL57Dialect을 사용해야 한다고 한다
MySQL8Dialect이 있지만 공식적으로 사용하는지 모르겠음
아마 schema.sql로 table 설정을 해줘야 하는 것 같았고, 없어도 해결가능해서 사용 안 함

profile
꾸준히 성실하게

0개의 댓글