Spring Boot 애플리케이션을 개발할 때, 테스트 코드 작성은 필수적입니다.
테스트를 잘 작성하면 버그를 사전에 방지할 수 있고, 코드 변경이 발생해도 안정성을 보장할 수 있습니다.
이번 글에서는 Spring Boot에서 JUnit을 활용한 테스트 케이스 작성 방법과 실전 팁을 정리했습니다.
단위 테스트부터 통합 테스트까지 모든 테스트 전략을 한눈에 정리할 수 있도록 구성했습니다.
✅ Spring Boot 테스트의 기본 개념
Spring에서의 테스트는 크게 두 가지로 나뉩니다.
1️⃣ 단위 테스트 (Unit Test)
- 하나의 메서드나 클래스가 올바르게 동작하는지 확인하는 테스트
- 보통 Mockito를 사용하여 Mock 객체를 활용
- DB나 외부 API와의 의존성을 제거하고 순수한 비즈니스 로직만 테스트
2️⃣ 통합 테스트 (Integration Test)
- 애플리케이션의 여러 계층이 정상적으로 동작하는지 확인하는 테스트
- 데이터베이스, API 호출, 보안 설정 등을 포함
- @SpringBootTest를 활용하여 애플리케이션의 실제 환경과 유사하게 실행
이제 본격적으로 JUnit을 활용한 테스트 작성 방법을 살펴봅시다.
🔹 Spring Boot에서 JUnit 테스트 설정
Spring Boot에서는 기본적으로 spring-boot-starter-test가 포함되어 있어 JUnit을 사용할 수 있다.
의존성을 확인하려면 pom.xml 파일에서 아래 내용을 확인하면 된다.
🛠 JUnit & Spring Boot Test Dependencies (pom.xml)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Spring Boot 2.2+ 버전부터는 기본적으로 JUnit5(Jupiter)가 포함되어 있다.
따라서 추가적인 설정 없이 바로 JUnit5를 활용할 수 있다.
✅ Spring Boot 단위 테스트 (Unit Test)
1️⃣ Service 레이어 단위 테스트 (Mockito 활용)
Service 클래스는 비즈니스 로직을 처리하며, 보통 Repository를 통해 데이터를 가져옵니다.
따라서 단위 테스트에서는 Repository를 직접 호출하지 않고 Mock 객체를 활용해야 합니다.
📌 예제: UserService 단위 테스트 (Mockito 사용)
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository; // 가짜 Repository
@InjectMocks
private UserService userService; // 실제 테스트 대상
@Test
void 유저_조회_성공() {
// given
User user = new User(1L, "testUser", "test@example.com");
when(userRepository.findById(1L)).thenReturn(Optional.of(user));
// when
UserDto result = userService.getUserById(1L);
// then
assertEquals("testUser", result.getName());
assertEquals("test@example.com", result.getEmail());
verify(userRepository, times(1)).findById(1L);
}
}
📌 테스트 설명
- @Mock: UserRepository의 가짜 객체(Mock)를 생성
- @InjectMocks: UserService에 userRepository를 주입
- when(...).thenReturn(...): 특정 입력값에 대해 반환값을 설정
- verify(...): 메서드가 몇 번 호출되었는지 검증
2️⃣ Repository 레이어 단위 테스트 (H2 Database 활용)
Repository 테스트는 실제 DB를 사용해야 정확한 테스트가 가능합니다.
테스트용으로는 H2 (In-Memory DB)를 활용하면 빠르게 테스트할 수 있습니다.
📌 예제: UserRepository 단위 테스트
@DataJpaTest // JPA 관련 설정만 로드
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void 유저_저장_조회_테스트() {
// given
User user = new User(null, "testUser", "test@example.com");
User savedUser = userRepository.save(user);
// when
Optional<User> foundUser = userRepository.findById(savedUser.getId());
// then
assertTrue(foundUser.isPresent());
assertEquals("testUser", foundUser.get().getName());
}
}
📌 테스트 설명
- @DataJpaTest: JPA 관련 설정만 로드하여 가볍게 실행
- 실제 데이터베이스 대신 H2 데이터베이스 사용
- userRepository.save(user): 데이터 저장 후 조회 테스트
✅ Spring Boot 통합 테스트 (Integration Test)
1️⃣ Controller 레이어 통합 테스트 (MockMvc 활용)
Controller 테스트는 API 요청을 수행하고 결과를 검증하는 과정이 필요합니다.
이를 위해 MockMvc를 사용하여 HTTP 요청을 모의 수행할 수 있습니다.
📌 예제: UserController 테스트 (MockMvc 활용)
@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserService userService; // Service를 Mocking
@Test
void 유저_조회_API_테스트() throws Exception {
// given
UserDto userDto = new UserDto(1L, "testUser", "test@example.com");
when(userService.getUserById(1L)).thenReturn(userDto);
// when & then
mockMvc.perform(get("/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("testUser"))
.andExpect(jsonPath("$.email").value("test@example.com"));
}
}
📌 테스트 설명
- @SpringBootTest: Spring 전체 컨텍스트를 로드
- @AutoConfigureMockMvc: MockMvc를 자동 설정
- mockMvc.perform(get("/users/1")): API 요청을 수행하고 결과 검증
🎯 Spring Boot 테스트 시 유용한 팁
✅ 1. @Transactional을 활용한 데이터 정리
테스트 실행 후 DB에 남는 데이터를 정리하려면 @Transactional을 사용하면 됩니다.
@Transactional
void 데이터_정리_테스트() {
// 테스트 실행 후 자동 롤백됨
}
✅ 2. Testcontainers를 활용한 실제 DB 테스트
H2 대신 실제 DB 환경에서 테스트하려면 Testcontainers를 활용할 수 있습니다.
@Testcontainers
@SpringBootTest
public class DatabaseIntegrationTest {
@Container
public static PostgreSQLContainer<?> postgreSQLContainer = new PostgreSQLContainer<>("postgres:13.3");
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl);
}
@Test
void DB_연결_테스트() {
assertTrue(postgreSQLContainer.isRunning());
}
}
✅ 3. CI/CD에서 테스트 자동화
GitHub Actions, Jenkins 등을 활용해 mvn test를 자동 실행하여 코드 푸시 시 테스트 검증
결론적으로 효율적인 Spring boot 테스트케이스 전략은 다음과 같습니다.
- 단위 테스트 → @Mock + Mockito 활용
- Repository 테스트 → @DataJpaTest + H2 DB 활용
- Controller 테스트 → MockMvc 활용
- 통합 테스트 → @SpringBootTest + Testcontainers 활용
'개발일지 > Spring' 카테고리의 다른 글
동시성 문제를 고려한 HashMap<>() 선택하기 (0) | 2025.02.07 |
---|---|
객체지향원칙을 고려한 Spring 테스트 설계 전략 (JUnit) (0) | 2025.02.06 |
Thymeleaf(타임리프) 템플릿엔진 ? (0) | 2025.02.06 |
Spring 중요한 라이브러리 (0) | 2025.02.06 |
Spring 프로젝트 기본 환경 설정 - Intellij (0) | 2025.02.06 |