Mockito가 뭔가요? 🤔
여러분, 영화 촬영장의 세트장을 상상해보세요! 실제 건물이 아니라 가짜 건물로 영화를 찍죠?
Mockito는 바로 이런 개념입니다!
- 실제 객체 대신 가짜(Mock) 객체를 만들어서
- 테스트하고 싶은 기능만 격리해서 테스트할 수 있게 해주는 프레임워크입니다
Mockito는 왜 필요한가요? 📌
독립적인 테스트 가능
- DB 연결 없이도 Repository 테스트 가능
- 외부 API 연동 없이도 서비스 테스트 가능
테스트 속도 향상
- 실제 DB 연결 없이 빠른 테스트 가능
- CI/CD 파이프라인 속도 개선
예측 가능한 테스트
- 테스트 시나리오를 완벽하게 통제 가능
- 랜덤한 외부 요인 제거
어떻게 사용하나요? 💻
1. Mock 객체 생성
// 방법 1: @Mock 애노테이션 사용
@Mock
private UserRepository userRepository;
// 방법 2: Mockito.mock() 메소드 사용
UserRepository userRepository = Mockito.mock(UserRepository.class);
2. Mock 동작 정의
// when-thenReturn 구문으로 동작 정의
when(metaMstRepository.findById("123"))
.thenReturn(Optional.of(new MetaMst("123", "테스트")));
// 여러 번 호출될 때 다른 결과 반환
when(metaMstRepository.findById("123"))
.thenReturn(Optional.of(new MetaMst("123", "첫번째")))
.thenReturn(Optional.of(new MetaMst("123", "두번째")));
3. 검증
// verify로 메소드 호출 검증
verify(metaMstRepository).findById("123");
verify(metaMstRepository, times(2)).findById("123");
주요 기능 모음 🎯
1. 메소드 동작 설정
// 특정 값 반환
when(repository.findById(anyString())).thenReturn(Optional.empty());
// 예외 발생
when(repository.save(any())).thenThrow(new RuntimeException());
// void 메소드
doNothing().when(service).deleteUser(anyString());
2. 인자 매칭
// 정확한 값 매칭
when(repository.findById("123")).thenReturn(...);
// 임의의 값 매칭
when(repository.findById(anyString())).thenReturn(...);
// 조건부 매칭
when(repository.findById(argThat(id -> id.startsWith("user")))).thenReturn(...);
3. 검증 기능
// 호출 횟수 검증
verify(repository, times(1)).findById("123");
verify(repository, never()).delete(any());
verify(repository, atLeastOnce()).findAll();
// 호출 순서 검증
InOrder inOrder = inOrder(repository, service);
inOrder.verify(repository).findById(anyString());
inOrder.verify(service).process(any());
실전 테스트 예제 📝
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void 사용자_조회_테스트() {
// given
String userId = "123";
User mockUser = new User(userId, "테스트유저");
when(userRepository.findById(userId))
.thenReturn(Optional.of(mockUser));
// when
User result = userService.getUser(userId);
// then
assertThat(result.getId()).isEqualTo(userId);
verify(userRepository).findById(userId);
}
}
주의사항 ⚠️
너무 많은 Mocking은 위험
- 실제 동작과 차이가 발생할 수 있음
- 통합 테스트도 적절히 병행 필요
Mock 객체의 한계
- 실제 객체의 모든 동작을 완벽하게 재현 불가
- 주요 시나리오 위주로 테스트 설계 필요
참고자료:
- Mockito 공식 문서: https://site.mockito.org/
- Spring 공식 문서: https://docs.spring.io/spring-framework/reference/testing.html
- Baeldung Mockito 가이드: https://www.baeldung.com/mockito-series
728x90