전제
장바구니 미션에서, H2 데이터베이스를 사용하고 있는데
리뷰어님이 알려주신 unsigned를 테이블의 id값에 붙여주기로 했다.
(DDL에서 정수 타입에 unsigned를 붙이면, 음수 값을 허용하지 않고 양수값의 범위를 더 넓혀준다)
하지만 H2 SQL은 unsigned를 지원하지 않아서, MySQL 문법으로 동작하도록 applicaition.properties 파일에서 아래와 같이 H2의 Mode를 설정했다.
spring.datasource.url=jdbc:h2:mem:shopping-cart-test;MODE=MYSQL
문제 상황
그런데 이를 설정한 뒤 테스트를 돌리니, @JdbcTest에서 예외가 발생했다.
잘못된 문법이어서 SQL문을 실행하지 못했고, 그로 인해 dataSource의 초기화와 JdbcTemplate 주입을 실패하고 있었다.
BIGINT 를 인식하지 못하는 것으로 보아 내가 설정한 url을 사용하지 않는 것이라 추측할 수 있었다.
nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "CREATE TABLE IF NOT EXISTS products ( id BIGINT [*]UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(30) NOT NULL, image_url VARCHAR(1000), price INT NOT NULL, PRIMARY KEY (id) )";
원인
디버깅을 해보니 applicaition.properties 파일에서 지정한 url이 아니라, 다른 url로 dataSource를 생성하고 있음을 발견했다.
아래는 @JdbcTest javadocs의 내용이다.
By default, tests annotated with @JdbcTest are transactional and roll back at the end of each test. They also use an embedded in-memory database (replacing any explicit or usually auto-configured DataSource). The @AutoConfigureTestDatabase annotation can be used to override these settings.
@JdbcTest는 기본적으로 임베디드 인메모리 데이터베이스를 사용한다. 따로 명시되었거나 설정된 dataSource 대신 위 디버깅에서 발견한 것과 같이 별도의 임베디드 인메모리 데이터베이스를 사용하는 것이다.
해결
대신 따로 설정해둔, 그러니까 내가 사용하려고 설정해둔 데이터베이스를 @JdbcTest에서 사용하고 싶다면
아래와 같이 @AutoConfigureTestDatabase 어노테이션의 replace 값을 Replace.NONE으로 설정해주면 된다.
@JdbcTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
class H2ProductDaoTest {
private final ProductDao productDao;
@Autowired
H2ProductDaoTest(final JdbcTemplate jdbcTemplate) {
this.productDao = new H2ProductDao(jdbcTemplate);
}
// ..
아래는 @AutoConfigureTestDatabase javadocs의 내용이다.
Annotation that can be applied to a test class to configure a test database to use instead of the application-defined or auto-configured DataSource. In the case of multiple DataSource beans, only the @Primary DataSource is considered.
이 어노테이션의 요소 중 replace는 "테스트 데이터베이스로 대체할 수 있는 항목"을 정의한다.
테스트에서 사용할 기본 DataSource 설정이 있을 때, 이를 대체할 수 있는지 조건(?)을 정의하는 것이다.
AutoConfigureTestDatabase.Replace 라는 이넘 타입이기 때문에 당연히 이 이넘의 상수로만 정의할 수 있다.
상수의 종류로는 아래 세가지가 있다.
1. ANY : 기존에 auto-configured되었거나 수동으로 정의된 DataSource가 있었더라도, 이를 대체할 수 있다.
2. AUTO_CONFIGURED : auto-configured된 DataSource는 이를 대체할 수 있다.
3. NONE : 어플리케이션의 기본 DataSource를 대체하지 않는다.
'공부 > Spring' 카테고리의 다른 글
Jpa 이벤트를 사용해 일관성 있는 시간 정보 관리하기 (0) | 2023.10.15 |
---|---|
성능 향상을 위한 Hikari Connection Pool 설정 for MySQL (1) (0) | 2023.09.29 |
Spring Boot의 로깅, 로깅을 왜 할까? (0) | 2023.05.23 |
@RequestBody 사용을 위한 DTO의 조건을 정리해보자 (0) | 2023.04.24 |
@Service, @Repository 사용 이유에 대한 고찰 + PSA (0) | 2023.04.20 |