
테스트에서 사용되는 Mockito의 Mock, Stub, Spy 개념을 각각 설명하고, 어떤 상황에서 어떤 방식을 선택해야 하는지 구체적인 예시와 함께 설명하세요.
예시) 사용자 생성 서비스에서 Repository 호출 여부 검증
@Test
void createUser_verifyRepositoryInteraction() {
UserRepository mockRepository = Mockito.mock(UserRepository.class);
UserService userService = new UserService(mockRepository);
User user = new User("test");
userService.create(user);
Mockito.verify(mockRepository).save(user);
}
예시) 사용자 조회 시 특정 ID로 고정된 User 객체 반환
@Test
void findUser_stubSpecificResponse() {
UserRepository stubRepository = Mockito.mock(UserRepository.class);
UserService userService = new UserService(stubRepository);
Mockito.when(stubRepository.findById(1L))
.thenReturn(Optional.of(new User("stubUser")));
User user = userService.findById(1L);
assertEquals("stubUser", user.getName());
}
예시) 실제 ArrayList를 기반으로 특정 메서드의 반환값을 변경하는 경우
@Test
void spyList_partialMocking() {
List<String> spyList = Mockito.spy(new ArrayList<>());
spyList.add("A");
spyList.add("B");
assertEquals(2, spyList.size());
Mockito.when(spyList.size()).thenReturn(100);
assertEquals(100, spyList.size());
assertEquals("A", spyList.get(0));
}
| 상황 | 적합한 방식 | 이유 및 설명 |
|---|---|---|
| 단순 메서드 호출 검증 | Mock | 특정 메서드의 호출 여부나 파라미터를 검증하기 쉬움 |
| 미리 정해진 조건의 응답 반환 | Stub | 특정 조건을 가정하고 원하는 반환값을 제공 |
| 일부 메서드만 행위 변경, 나머지는 실제 로직 실행 | Spy | 실제 객체를 기반으로 최소한의 메서드만 변경할 수 있어 테스트가 더 현실적 |