Spring Boot로 개발을 하다 보면, 테스트는 선택이 아닌 필수입니다.
JUnit5의 핵심 개념과 함께, Spring Test에서 어떻게 활용하는지에 대해 설명합니다.
1. JUnit5란 무엇인가?
JUnit5는 자바 진영에서 가장 널리 사용되는 테스트 프레임워크인 JUnit의 최신 버전입니다.
JUnit4에서 구조적으로 개선된 점이 많고, 다양한 확장 기능이 포함되어 있어 Spring 환경에서도 유연하게 사용할 수 있습니다.
주요 구성 요소
- JUnit Platform: 테스트 실행 엔진
- JUnit Jupiter: JUnit5의 API와 테스트 어노테이션 제공
- JUnit Vintage: JUnit3, JUnit4 백워드 호환
2. JUnit5 기본 어노테이션
@Test // 테스트 메서드
@BeforeEach // 각 테스트 실행 전 실행
@AfterEach // 각 테스트 실행 후 실행
@BeforeAll // 전체 테스트 시작 전 1회 실행 (static)
@AfterAll // 전체 테스트 종료 후 1회 실행 (static)
@DisplayName // 테스트 설명
예시:
class CalculatorTest {
private Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
@DisplayName("덧셈 연산 테스트")
void testAdd() {
assertEquals(5, calculator.add(2, 3));
}
}
3. Spring Boot와 통합 테스트
Spring Boot에서는 단순한 단위 테스트 외에, 빈 생성부터 DI까지 포함한 통합 테스트도 가능해야 합니다.
이를 위해 사용하는 어노테이션이 @SpringBootTest
입니다.
예시
@SpringBootTest
class UserServiceTest {
@Autowired
private UserService userService;
@Test
void getUserTest() {
User user = userService.getUserById(1L);
assertNotNull(user);
}
}
동작 방식
- Spring Boot 애플리케이션 전체 컨텍스트 로딩
- 테스트 중 DI, 트랜잭션, 프로파일 등 실제 운영환경과 유사한 환경 제공
- 기본적으로
test
프로파일이 사용됨
4. @WebMvcTest와 슬라이스 테스트
모든 빈을 로딩하지 않고 특정 계층만 테스트할 수도 있습니다.
대표적으로 컨트롤러 레이어만 테스트하고 싶을 때 @WebMvcTest
를 사용합니다.
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService;
@Test
void getUserTest() throws Exception {
given(userService.getUserById(1L)).willReturn(new User(1L, "홍길동"));
mockMvc.perform(get("/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("홍길동"));
}
}
@MockBean
을 사용하면 실제 빈 대신 모킹 객체를 주입할 수 있습니다.
5. 테스트에서 트랜잭션 처리
@Transactional
을 테스트 클래스나 메서드에 붙이면 각 테스트가 완료된 후 자동 롤백됩니다.
@SpringBootTest
@Transactional
class UserRepositoryTest {
...
}
이를 통해 테스트 후 DB에 데이터가 남지 않아 테스트 간 영향이 없습니다.
6. TestEntityManager 활용
JPA 관련 테스트에서는 TestEntityManager
를 활용하면 더 정교한 검증이 가능합니다.
@DataJpaTest
class UserRepositoryTest {
@Autowired
private TestEntityManager em;
@Autowired
private UserRepository userRepository;
@Test
void findByNameTest() {
User user = new User("김철수");
em.persist(user);
em.flush();
Optional<User> found = userRepository.findByName("김철수");
assertTrue(found.isPresent());
}
}
결론
단위 테스트는 빠른 피드백 루프를 제공하고, 통합 테스트는 시스템 전반의 신뢰성을 검증합니다.
Spring Boot에서는 JUnit5와 다양한 테스트 어노테이션을 통해 계층별로 필요한 테스트를 유연하게 작성할 수 있습니다.
테스트는 시간이 드는 일이지만, 장기적으로는 개발 생산성과 안정성을 모두 높이는 투자입니다.
'개발 > JAVA' 카테고리의 다른 글
Spring MVC 요청 처리 흐름 이해하기 (0) | 2025.09.29 |
---|---|
Postman vs Insomnia: API 테스트 도구 완전 정복 (0) | 2025.09.28 |
Spring Boot에서 @Value를 사용해 properties 값 주입하기 (0) | 2025.09.26 |
Spring Boot에서 SLF4J와 Logback으로 로깅 설정하기 (0) | 2025.09.25 |
Spring Boot DevTools 활용하기 – 개발 생산성을 높이는 자동 리로드 기능 (0) | 2025.09.24 |