Mock
정의
- 실제 객체를 대체하는 ‘가짜 객체’로, 내부 동작이 구현되어 있지 않고 원하는 동작을 명시적으로 지정해야 한다.
- 테스트를 위해 만든 "가짜 객체" 그 자체, 동작을 지정하면 Stub
- 메서드의 반환값, 예외 발생 등을 사전에 설정할 수 있으며, 메서드 호출 여부(verify)도 검증할 수 있다.
특징
- 실제 로직은 실행되지 않음
- 모든 동작은 명시적으로 지정해야 함 -> Stub
- 테스트 대상과의 상호작용(호출 여부, 호출 횟수 등) 검증에 적합
예시
List<String> mockList = Mockito.mock(List.class);
Mockito.when(mockList.size()).thenReturn(5);
assertEquals(5, mockList.size());
Mockito.verify(mockList).size();
적합한 상황
- 외부 시스템, 복잡한 의존성 등 실제 객체를 사용하기 어려울 때
- 호출 여부, 횟수, 파라미터 등 상호작용 자체를 검증할 때
- 테스트 격리와 속도가 중요한 경우
Stub
정의
- Mockito에서는 보통 Mock 객체에 대해 when(...).thenReturn(...) 또는 doReturn(...).when(...)을 사용해 Stub을 만든다.
특징
- Mock(혹은 Fake) 객체에 "특정 메서드가 호출되면 정해진 값을 반환"하도록 미리 행동을 지정한 것
- 실제 객체의 동작을 단순화하여 테스트 대상의 환경을 제어
- 복잡한 로직 없이, 입력에 대해 미리 정해진 결과만 반환
예시
List<String> mockList = Mockito.mock(List.class);
Mockito.when(mockList.size()).thenReturn(10);
assertEquals(10, mockList.size());
적합한 상황
- 테스트 대상이 의존하는 객체의 특정 동작만 제어하고 싶을 때
- 외부 시스템의 상태나 결과를 시뮬레이션할 때
- 예외 상황, 경계값 등 다양한 시나리오를 쉽게 구현하고 싶을 때
Spy
정의
- 실제 객체를 감싸서 만들어진 부분 Mock 객체
- 실제 객체의 동작을 대부분 유지하면서, 특정 메서드만 Stub하거나 호출 여부를 감시할 수 있다.
특징
- 실제 객체의 메서드가 기본적으로 실행됨
- 필요한 메서드만 Stub 가능
- 호출 기록(verify)도 가능
예시
public class SimpleService {
private final List<String> store = new ArrayList<>();
public void add(String value) {
store.add(value);
}
public int count() {
return store.size();
}
public String get(int index) {
return store.get(index);
}
}
public class SimpleServiceTest {
@Test
void spyExample() {
SimpleService realService = new SimpleService();
SimpleService spyService = spy(realService);
spyService.add("A");
spyService.add("B");
assertEquals("A", spyService.get(0));
doReturn(100).when(spyService).count();
assertEquals(100, spyService.count());
assertEquals("B", spyService.get(1));
verify(spyService, times(2)).add(anyString());
}
}
적합한 상황
- 실제 객체의 동작 대부분은 그대로 두고, 일부만 제어하거나 감시하고 싶을 때
- 상태 변화가 중요한 객체의 일부 동작만 가짜로 만들고 싶을 때
- 복잡한 객체에서 전체 Mock이 오히려 번거로울 때
선택 기준 및 실무 예시

- 실무에서는 Mock과 Stub을 혼용하며, 실제 객체의 일부만 제어가 필요하면 Spy를 사용