기록하기 위한 글이라 설명이 친절하지 않을 수 있습니다.
나는 core 모듈에 도메인 엔티티와 리포지토리, 서비스를 만들고 있다
근데 application 클래스를 rest 모듈에 가지고 있었다.
나는 jpa 리포지토리를 사용하기 때문에 구현체를 내가 만들 수 없었고 (mocking 말고 실제 리포지토리)
그래서 그동안 리포지토리를 테스트 클래스에 DI 하고 싶으면 rest 모듈에서 했어야했다.
그리고 나서 확인하고 싶은 것이 확인되면 테스트 클래스를 삭제하고는 했다. 여기(core모듈에) 있으면 안 될 것 같아서.
그런데 이제 그렇게 하기 싫었다. 테스트를 만드는 그 때보다는, 새로운 기능들을 만들며 계속 테스트를 돌리는 데에 의의가 굉장히 크다고 생각하기 때문에 저장을 하고 싶었고, 그래서 core 모듈에서 di를 할 방법을 찾기 시작했다.
처음엔 그냥 내가 테스트하는 클래스에 @SpringBootApplication
을 붙였다. (개무식)
그리고 테스트를 실행해보았다.
테스트가 정상동작하지 않았고, 예외는 다음과 같았다.
org.springframework.beans.factory.UnsatisfiedDependencyException:
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;
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'dataSource': Invocation of init method failed
Caused by: 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.
@DataJpaTest
문서를 보면 다음과 같이 설명돼있다.
By default, tests annotated with @DataJpaTest 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.
자동으로 embedded in-memory db를 사용한다는 것이다. 나는
선생님께서는 이렇게 하라고 하셨다.
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
테스트 db를 사용하지 않도록 설정을 해주고 다시 돌려봅시다.
(대충 기록만..)
Error creating bean with name 'entityManagerFactory'
...
Caused by: org.hibernate.AnnotationException: @OneToOne or @ManyToOne
on com.zoin.rendezvous.domain.notification.FriendNotification.friendRelationship references an unknown entity: com.zoin.rendezvous.domain.friend.Friend
아무튼 FriendNotification 엔티티가 참조하는 Friend 엔티티를 못찾는다는 얘기다.
이유는 @SpringBootApplication이 붙은 클래스(FriendNotificationTest)의 위치때문이다.
마찬가지로 문서를 보면, @SpringBootApplication
은 `@ComponentScan라는 어노테이션을 포함하고 있고, base package의 default 값이 해당 클래스가 속한 패키지가 된다고 써있다.
후 이걸 까먹따니. 이거 베이스 패키지 어노테이션으로 설정해줄 바에는 전역으로 쓸 수 있게 test base 패키지에 클래스하나 만드는게 낫겠다는 판단을 했다. 그래서 다음처럼 추가해줬더니 잘 돌아간다.
오예
+) 외에도 Kotest 에서 EntityManager가 정상 동작하게 하려면 kotest의 spring extension을 사용해야 한다.
참고