soft delete기능을 구현하여 테스트를 진행해보았다.
지금까지는 DB테스트는 모두 가짜(Mock)로 테스트를 했다.
왜냐하면 JPA는 완성된 제품이기 때문에 굳이 테스트를 할 필요가 없기 때문이다.
하지만 DB + 비즈니스로직을 같이 테스트 할 때는 DB의 작동을 고려해 통합 테스트가 필요한 경우가 있다.
(Soft delete에서 Delete가 Update로 잘 바뀌는지 보고 싶기 때문)
그래서 테스트를 작성해 보았다.
검색을 해보니 @DataJpaTest를 사용한다고 한다.
그래서 작동이 되나 테스트를 해볼겸 Hello를 출력해 보았다.
@DataJpaTest
class PostRepositoryTest {
@Test
void name() {
System.out.println("hello");
}
}
Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Failed to replace DataSource with an embedded database for tests. If you want an embedded database please put a supported one on the classpath or tune the replace attribute of @AutoConfigureTestDatabase.
dataSource를 Bean으로 등록하지 못했다고 한다.
그러고는 database를 embedded하고 싶으면 @AutoConfigureTestDatabase의 설정을 하라라고하는거같은데...
구글링을통해 단서를 었었다.
우선 처음부터 차근차근 살펴보자
에러의 시작인 @DataJpaTest를 확인해 보았다.
여러 어노테이션들이 있지만 주목해야할 것은 @Transactional과 @AutoconfigureTestDataBase이다.
(@DataJpaTest를 사용하면 추가로 트랜잭션을 선언해줄 필요가 없고, 테스트가 끝나면 자동으로 롤백이 적용.)
그중 아까 에러에서 보았던 @AutoconfigureTestDataBase를 찾았다.
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.
위의 정보는 @DataJpaTest의 주석내용이다.
여기서 내장된 메모리 데이터베이스를 사용하고, @AutoconfigureTestDataBase를 통해 DB를 Override할 수 있다고 나온다.
이제 원인을 파악하였다.
내장된 DB이건 Override할 DB이건 설정을 해줘야 할거같다는 느낌이 들엇다.
그래서 검색을 또 해보았다.
testImplementation 'com.h2database:h2'
위의 코드처럼 Test에서 h2 database를 사용하겠다는 뜻이다.
Test용 apllication.yml도 작성해 주었다.
server:
servlet:
encoding:
force-response: true
spring:
jpa:
hibernate:
ddl-auto: update
show-sql: true
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1
username: sa
password:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
h2:
console:
enabled: true
이렇게 해주고 테스트를 돌려보니
테스트가 정상작동 하였다.
결론은 @DataJpaTest는 DB를 테스트 하는 것이고 테스트할때 사용할 DB를 정의해줘야 한다는 것인데
오류가 났던 이유는 DB를 설정하지 않아서 이다!