Spring Repository 슬라이스테스트 코드 작성

선종우·2023년 5월 10일
0

1. 공부배경

이전에는 무작전 @SpringBootTest를 사용하였는데, 이럴 경우 모든 빈들이 등록되어야 하기 때문에 테스트가 무거워지는 문제점이 있다고 한다. 구현 단계별 단위테스트 방법을 공부해서 필요한 시점에 필요한 테스트만 진행할 수 있도록 정리하려고 한다. 이번 글에서는 그중 Repository 테스트를 진행할 때 필요한 내용들을 정리하였다.

  • @SpringBootTest의 경우 실제 DB를 그대로 사용하며, 롤백을 위해서는 @ Transactional을 별도로 설정해줘야 한다.

2. 공부 내용

a. @DataJpaTest

@DataJpaTest
class ArticleRepositoryTest{
  테스트 코드
}
  • 그런데 위 테스트를 실행했더니 아래와 같은 오류가 발생했다.
Caused by: 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; 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.
  • 로컬 PC에 in-memory DB가 없어 생긴 에러로 나는 추가DB 설정 없이 실제 Spring에 연동되는 MySQL DB를 사용하고 싶었다. 이럴 경우에는 @AutoConfigureTestDataBase애노테이션 설정을 통해 기존 DB를 그대로 사용할 수 있도록 해주어야 한다. 테스트 코드를 아래와 같이 바꿨다.(H2 DB를 사용할 거라면 건드릴 필요 없음)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@DataJpaTest
class ArticleRepositoryTest{
  테스트 코드
}
  • 그런데 이번에는 아래와 같은 오류가 발생했다.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.jscode.demoApp.repository.ArticleRepositoryTest': Unsatisfied dependency expressed through field 'articleRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.jscode.demoApp.repository.ArticleRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
  • 분명 Repository에 @Repository를 사용했는데도 빈을 찾지 못하고 있다.현재 나는 공부 목적으로 @JpaRepository를 상속하지 않고 Repository를 구현하고 있다. 그런데 이런 경우 내가 구현한 빈은 일반적인 @Component로 인식되어 빈이 생성되지 않는다고 한다. 그렇기 때문에 테스트에서 내가 구현한 클래스(이 경우 ArticleRepositoryWithVanillaJpa.class)를 사용하고 싶으면 명시적으로 Import를 해주어야 한다. 또한 Jpa관련 설정을 한 별도 @Configuration 빈이 있는 경우에도 같이 Import해준다. 테스트 코드를 아래와 같이 바꿨다.
@Import({JpaConfig.class, ArticleRepositoryWithVanillaJpa.class})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@DataJpaTest
class ArticleRepositoryTest{
  테스트 코드
}
  • 추가로 별도 test propery를 따로 관리하고 싶다면, 아래와 같은 애노테이션을 추가해준다. @TestPropertySource(locations = "classpath:application-test.properties")

3. 정리

  • Repository에 대한 단위테스트를 진행하고 싶다면, 아래와 같이 설정하면 된다.
    - @DataJpaTest 선언
    - @AutoConfigureTestDatabase 선언(memory DB를 사용하지 않은 경우)
    - @Import 선언 : @DataJpaTest 선언에 따라 자동 주입이 불가능한 경우 Config나 Repository 빈이 있는 경우
    - @TestPropertySource 선언 : 별도 테스트 프로퍼티 파일이 있는 경우
@TestPropertySource(locations = "classpath:application-test.properties")
@Import({JpaConfig.class, ArticleRepositoryWithVanillaJpa.class})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@DataJpaTest
class ArticleRepositoryTest{
  테스트 코드
}

0개의 댓글