단위 테스트는 필수적인 작업이라고 생각한다. 단위 테스트는 어플리케이션의 특정 기능이 기대한 대로 동작하는지 확인하는 데 도움을 준다. 이 글에서는 JUnit과 Mockito를 사용해서 Spring 어플리케이션에서 단위 테스트를 작성하는 방법을 설명하려고 한다.
JUnit은 Java에서 가장 많이 사용되고 있는 테스트 프레임워크다. Spring은 JUnit 5를 기본적으로 지원하며, 단위 테스트를 작성하고 실행하기 위한 다양한 기능을 지원한다.
Spring에서 JUnit을 사용하여 테스트하려면 spring-boot-starter-test 의존성을 추가해야한다. 이 라이브러리는 JUnit뿐만 아니라 Mockito, AssertJ 등의 라이브러리가 포함되어 있다.
testImplementation 'org.springframework.boot:spring-boot-starter-test'
아래는 Spring 서비스의 간단한 단위 테스트 예제이다. 이 테스트는 CalculatorService의 add 메서드가 올바르게 작동하는 확인한다.
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.asertEquals;
public class CalculatorServiceTest {
private final CalculatorService calculatorService = new CalculatorService();
@test
void testAdd() {
int result = calculatorService.add(2, 3);
assertEquals(5, result);
}
}
Spring은 @SpringBootTest
어노테이션을 사용해서 어플리케이션 컨텍스트를 불러온 후 통합 테스트를 수행할 수 있다. 하지만 단위 테스트는 어플리케이션 컨텍스트를 불러오지 않고, 빠르고 간단하게 특정 기능을 테스트하는 것이 목표다.
Mockito는 Spring에서 가장 많인 사용되는 모킹(Mock) 프레임워크다. Mockito를 사용하면 객체의 메서드 호출을 모킹하여 의존성을 쉽게 대체할 수 있다.
다음은 BoardService
의 createBoard
메서드를 테스트하기 위해 Mockito를 사용하는 방법이다.
// BoardService
@RequiredArgsConstructor
@Service()
public class BoardService {
private final BoardRepository boardRepository;
public void createBoard(BoardDto boardDto) {
boardRepository.save(boardDto.toEntity());
}
}
import board.board_spring.domain.board.dto.BoardDto;
import board.board_spring.domain.board.entity.Board;
import board.board_spring.domain.board.repository.BoardRepository;
import board.board_spring.domain.board.service.BoardService;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
class BoardServiceTest {
@Mock
private BoardRepository boardRepository;
@InjectMocks
private BoardService boardService;
@Test
void testCreateBoard() {
// Given
BoardDto boardDto = BoardDto.builder()
.title("Test Title")
.content("Test Content")
.build();
Board boardEntity = boardDto.toEntity();
// Mocking: boardRepository.save() 호출 시 모킹된 응답 반환
when(boardRepository.save(any(Board.class))).thenReturn(boardEntity);
// When
Board result = boardService.createBoard(boardDto);
// Then
assertEquals(boardEntity, result); // 결과가 예상된 값과 같은지 확인
verify(boardRepository, times(1)).save(any(Board.class)); // save 메서드가 1번 호출되었는지 확인
}
}
JUnit과 Mockito는 서로 보완적인 역할을 한다. JUnit은 테스트 프레임워크로서 테스트 케이스를 관리하고 실행하는 역할을 하며, Mockito는 테스트 중에 의존성을 모킹하면서 단위 테스트를 단순화하고, 특정 메서드나 객체 간의 상호작용을 검증할 수 있게 한다.
이 두 가지를 함께 사용하면, 다음과 같은 장점이 있다.
Spring에서 JUnit과 Mockito를 사용하여 단위 테스트를 작성하는 방법을 알아봤다. JUnit은 테스트 케이스 관리와 실행을 담당하고, Mockito는 의존성을 모킹하여 단위 테스트의 정확성과 독립성을 높인다. 이를 통해 보다 안정적인 유지보수 가능한 코드를 작성할 수 있다.