Mock vs Stub vs Spy

썬쑨·2025년 5월 18일

Spring

목록 보기
10/12

✅ 1. Mock

: 가짜 객체(Fake)를 생성하여 행동만 정의하고 내부 로직은 모두 비워진 객체로, 실제 로직은 수행되지 않으며, 호출 여부나 횟수 등을 검증하는 용도로 사용한다. 모든 메서드가 기본값을 반환한다.(null, 0, false 등)

  • 언제 사용하나?
    : 테스트 대상 객체놔 상호작용만 검증하고 싶을 때 사용.
  • ex)
@ExtendWith(MockitoExtension.class)
class UserServiceTest {

    @Mock
    EmailSender emailSender; // send 메서드는 진짜 호출되지 않음

    @InjectMocks
    UserService userService;

    @Test
    void testEmailIsSent() {
        userService.registerUser("test@example.com");

        verify(emailSender).send("test@example.com"); // send 호출 여부만 확인
    }
}

✅ 2. Stub

: 가짜 객체에 대해 특정 메서드 호출 시 미리 정의한 값을 반환하도록 설정. 즉, "무엇을 반환할지"를 고정하는 방식이다. Mock/Spy와 함께 사용한다. ex) when().thenReturn() ...

  • 언제 사용하나?
    : 테스트 대상 객체의 동작을 위해 외부 의존 객체의 응답을 고정시켜야 할 때 사용.
  • ex)
@Test
void testExistingUserLogin() {
    User mockUser = new User("test@example.com");

    when(userRepository.findByEmail("test@example.com"))
        .thenReturn(mockUser); // 특정 입력에 대해 결과를 고정 (Stub)

    User user = userService.login("test@example.com");

    assertEquals("test@example.com", user.getEmail());
}

3. Spy

: 실제 객체를 감싸서, 일부는 진짜로 호출하고 일부는 조작할 수 있는 부분 Mock으로, 원래 동작을 유지하면서도 특정 메서드만 가로채거나 검증이 가능하다.

  • 언제 사용하나?
    : 실제 로직이 중요하지만, 특정 메서드만 결과를 통제하거나 검증하고 싶을 때 사용.
  • ex)
class Calculator {
    public int add(int a, int b) { return a + b; }
    public int multiply(int a, int b) { return a * b; }
}

@Spy
Calculator calculator = new Calculator();

@Test
void testSpyPartialStub() {
    doReturn(10).when(calculator).add(3, 5); // add만 조작

    int result = calculator.add(3, 5); // 10이 반환됨
    int mul = calculator.multiply(2, 3); // 실제 multiply는 호출됨

    assertEquals(10, result);
    assertEquals(6, mul);
}

이처럼 Mockito의 다양한 방식은 각각의 목적과 역할이 분명히 구분되므로, 이를 상황에 맞게 판단하고 일관성 있게 적용하는 것이 중요하다.


https://www.browserstack.com/guide/mockito-spy-vs-mockito-mock
https://kimjongmo.github.io/spring/mock-vs-spy

profile
천천히 굴러갑니다!

0개의 댓글