Today I Learned
#Repository 테스트 방식 정리
1. `@DataJpaTest` — JPA 전용 슬라이스 테스트
가장 널리 쓰이는 방식으로, JPA 관련 Bean만 로딩하여 빠르고 가볍게 테스트 가능
@DataJpaTest
class CommentRepositoryTest {
@Autowired
private CommentRepository commentRepository;
@Test
void 댓글_저장_테스트() {
Comment comment = new Comment("내용");
Comment saved = commentRepository.save(comment);
assertThat(saved.getId()).isNotNull();
}
}
- 장점: 빠름, 설정 간단, 슬라이스 테스트에 적합
- 단점: Service, Security 등 다른 Bean은 로딩되지 않음
2. `@SpringBootTest` + 실제 DB — 통합 테스트
전체 애플리케이션 컨텍스트를 로딩하여 실제 환경과 유사하게 테스트
@SpringBootTest
@Transactional
class CommentRepositoryIntegrationTest {
@Autowired
private CommentRepository commentRepository;
@Autowired
private UserRepository userRepository;
@Test
void 댓글과_사용자_연관관계_테스트() {
User user = userRepository.save(new User("tester"));
Comment comment = new Comment("내용", user);
commentRepository.save(comment);
List<Comment> comments = commentRepository.findByAuthorId(user.getId());
assertThat(comments).hasSize(1);
}
}
- 장점: 실제 환경과 유사, 연관관계 테스트에 적합
- 단점: 느림, 설정 복잡, 테스트 간 간섭 가능
3. `TestEntityManager` 활용 — JPA 동작 상세 확인
`@DataJpaTest` 환경에서 JPA의 `flush`, `persist` 동작을 직접 제어 가능
@Autowired
private TestEntityManager em;
@Test
void flush_테스트() {
Comment comment = new Comment("내용");
em.persist(comment);
em.flush(); // DB에 반영
Comment found = em.find(Comment.class, comment.getId());
assertThat(found.getContent()).isEqualTo("내용");
}
- 장점: JPA 내부 동작 확인 가능
- 단점: 실무에서는 자주 쓰이지 않음, 학습용에 적합
4. `@Sql` 또는 `@BeforeEach`로 테스트 데이터 세팅
테스트마다 필요한 데이터를 미리 세팅하여 반복 제거
@BeforeEach
void setup() {
userRepository.save(new User("tester"));
taskRepository.save(new Task("작업"));
}
@Sql("/test-data.sql")
class CommentRepositoryTest { ... }
- 장점: 테스트 간 일관된 데이터 유지
- 단점: 관리 복잡, 데이터 충돌 가능
5. Testcontainers — 실제 DB 환경에서 테스트
Docker 기반 DB 컨테이너를 띄워서 테스트. 실무에서 점점 많이 사용됨
@Testcontainers
@SpringBootTest
class CommentRepositoryTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15");
@DynamicPropertySource
static void overrideProps(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
}
- 장점: 실제 DB 환경, CI/CD에 적합
- 단점: 설정 복잡, 테스트 속도 느림
※목적에 따른 방식
| 목적 | 추천 방식 |
| 빠른 CRUD 테스트 | `@DataJpaTest` |
| 연관관계 포함 통합 테스트 | `@SpringBootTest` |
| JPA 동작 학습 | `TestEntityManager` |
| CI/CD 환경 테스트 | `Testcontainers` |
| 고정된 테스트 데이터 | `@Sql` or `@BeforeEach` |
마치며
Repository 테스트를 해보니, 단순히 저장하고 조회하는 것만이 아니라 데이터 흐름을 확인하는 데 정말 중요하다는 걸 알게 됐다. 특히 여러번의 시행착오를 겪으며 연관된 객체(User, Task 등)를 먼저 저장해야 오류 없이 테스트가 된다는 알게 되었고, 테스트 방식도 다양해서 상황에 따라 잘 사용하는 것도 중요하다는 걸 느꼈다. 무엇보다 테스트를 하면서 코드 구조와 역할이 더 잘 보이게 된 게 가장 큰 배움이었다.