Spring 3.1.5 + Jpa + MySQL 환경에서 토이프로젝트를 진행 중인데, 프로덕트 db의 데이터 때문에 test가 제대로 되지 않아서 test용 db 분리의 필요성을 느꼈다.
그래서 h2를 test용 db로 사용하기로 결정했다.
test용 db 분리를 하면서 겪은 시행착오들과 해결 방법들을 적어보고자 한다.
3일 동안 고통받고 겨우 해결했다.
runtimeOnly 'com.h2database:h2'
추가
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
jdbc:h2:mem:{db이름}
으로 In-Memory mode로 사용했다.MODE=MYSQL
를 써줘야 MySQL을 인식한다.jdbc:h2:tcp://localhost/~/{db이름}
으로 작성한다.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);
}
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 {
...
}
application.yml에서 dialect: org.hibernate.dialect.MySQL5InnoDBDialect
사용시 에러 발생함
원인 & 해결 : MySQL5InnoDBDialect
는 deprecated되었고, 따라서 MySQL57Dialect
을 사용해야 한다고 한다
MySQL8Dialect
이 있지만 공식적으로 사용하는지 모르겠음
아마 schema.sql로 table 설정을 해줘야 하는 것 같았고, 없어도 해결가능해서 사용 안 함