단위테스트를 작성 간에 두 애노테이션 모두 사용해보면서 알게 된 내용을 기록한다.
@SpringBootTest
@SpringBootTest는 ApplicationContext(스프링 컨테이너)의 모든 Bean들을 등록한다.
즉 스프링 부트를 사용해 테스트를 한다는 말인데,
1. 쉽게 말해 @Configuration을 통해 수동으로 등록한 Bean들과,
2. 컴포넌트 스캔을 통해 @Component가 달려있는 모든 Bean들을 등록한다는 뜻이다.
설정 파일의 경우 test 폴더 내에 application.yml을 사용한다.
만약 test 폴더 내에 따로 설정 파일을 지정하지 않았다면, 기본 java 폴더 내에 application.yml 설정을 따른다.
datasource는 in-memory, 로컬, 외부 상관없이 DB를 지정할 수 있다.
만약 따로 지정하지 않는다면 in-memory DB를 사용한다.
예를 들어, h2 데이터베이스 라이브러리를 추가한 경우, 이렇게만 설정해도 h2 memDB의 ddl-auto: create-drop을 따른다.
spring:
jpa:
properties:
hibernate:
format_sql: true
logging.level:
org.hibernate.SQL: debug
애노테이션은 테스트 클래스 위에 위치한다.
@SpringBootTest
@Transactional
public class AccountValidationTest {
}
@Transactional을 붙여주면 테스트할 때마다 DB가 롤백된다.
만약 특정 테스트에 대해 롤백을 원하지 않는 경우 @Rollback 애노테이션을 붙여주면 된다.
@SpringBootTest
@Transactional
public class AccountValidationTest {
@Test
@Rollback(value = false)
void test() {
}
}
@DataJpaTest
@DataJpaTest는 오직 JPA 컴포넌트들만을 테스트하기 위한 애노테이션이다.
ApplicationContext 전체가 아닌 JPA에 필요한 설정들에 대해서만 Bean을 등록한다.
즉 컴포넌트 스캔을 하지 않아, @Component 빈들이 등록되지 않는다.
@DataJpaTest 애노테이션을 자세히 보자.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
...
@Transactional
...
@AutoConfigureTestDatabase
...
public @interface DataJpaTest {
...
}
@Transactional: @DataJpaTest는 @Transactional 애노테이션을 포함하기 때문에, 따로 붙여주지 않아도 각 테스트 종료시 DB가 자 동으로 롤백된다.
@AutoConfigureTestDatabase: 기본적으로 in-memory DB를 활용해서 테스트가 실행된다.
비교
@SpringBootTest의 경우 @Component 애노테이션이 붙은 클래스를 사용해야 하는 경우에 활용하자.
예를 들어, 컨트롤러, 서비스 테스트에 활용할 수 있다.
@DataJpaTest는 @Component 빈을 등록하지 않아 테스트 실행 속도가 빠르다.
@Component 빈을 활용하지 않는 경우 고려해보자.
예를 들어, 레포지토리, 일반 비즈니스 로직 테스트에 활용할 수 있다.
나는 처음에 레포지토리 테스트에 @DataJpaTest를 사용하고,
서비스, 컨트롤러 테스트에 @SpringBootTest를 통해 사용했다.
이러다 보니 매번 스프링 부트를 켜야 해서 테스트 개수가 많아짐에 따라 단위테스트가 무거워진다는 느낌을 받았다.
따라서 상대적으로 가벼운 @DataJpaTest를 사용한 레포지토리 테스트는 유지하고,
서비스 테스트에서는 레포지토리 Mock 객체를, 컨트롤러 테스트에서는 서비스 Mock 객체를 사용하는 방식으로 결정했다.
참고자료
https://velog.io/@jwkim/spring-boot-datajpatest-springboottest
https://da-nyee.github.io/posts/spring-springboottest-vs-datajpatest/
'java > spring' 카테고리의 다른 글
[Spring] junit test에서 lombok 사용하는 방법 (0) | 2024.10.16 |
---|---|
[Spring] ControllerAdvice - 예외 처리 (2) | 2023.07.16 |
[SpringMVC] 타임리프 - 기본기능 (0) | 2023.07.08 |
[Spring] DTO의 사용 범위 (0) | 2023.06.27 |
[Spring] Service - 인터페이스 도입과 버저닝 (0) | 2023.06.26 |