TDD 회고록: 단위 테스트, 값 넣고 값 나오면 되는 거 아니야?

단위 테스트, 값 넣고 값 나오면 되는 거 아니야?

 

서론

 

테스트 코드를 처음 접했을 때, 이런 생각이 들었다.

 

“단위 테스트? 그냥 값 넣고 값 나오면 되는 거 아닌가?”

 

그렇게 생각하고 @Mock도 쓰고, @InjectMocks도 쓰면서 뿌듯하게 테스트를 짰다.

하지만 단위 테스트, 통합 테스트, E2E 테스트까지 공부해보니 내가 하고 있던 게 진짜 단위 테스트가 아니었다는 걸 알게 됐다.

 

이 글은 그런 과정을 통해 내가 직접 겪고 정리한 테스트에 대한 이해를 담고 있다.

부족한 내용이 있을 수 있지만, 나처럼 막 시작한 사람에게는 도움이 될 거라 생각한다.

 


 

📚 테스트 더블(Test Double) 역할별 정리

 

테스트 더블은 테스트 대상 객체가 의존하는 외부 객체들을 대신하는 가짜 객체입니다.

실제 구현 대신 테스트 목적에 맞게 동작을 흉내 내어 테스트를 빠르고 안정적으로 수행할 수 있도록 돕습니다.

 


 

역할별 설명

 

1. Dummy

  • 테스트 코드에서 인자가 필요하지만 실제로 테스트에 사용되지 않는 경우
  • 내부 로직이나 상태와 무관하게 단순히 자리를 채우는 역할
User dummyUser = new User(null, null); // 실제로 값은 사용하지 않음

 


 

2. Stub

  • 특정 메서드 호출에 대해 미리 정해진 응답을 반환
  • 상태 기반 테스트에 적합하며, 테스트 대상이 의존하는 객체의 행동을 통제 가능
  • Mockito 기준 when().thenReturn() 사용
@ExtendWith(MockitoExtension.class)
class UserServiceTest {

    @Mock
    UserRepository userRepository;

    @InjectMocks
    UserService userService;

    @Test
    void chargePoint_ShouldThrow_WhenUserNotFound() {
        // Stub: userId를 넣으면 무조건 null 반환되게 설정
        when(userRepository.findByUserId("invalidUser")).thenReturn(Optional.empty());

        assertThrows(CoreException.class, () -> {
            userService.chargePoint("invalidUser", 1000);
        });
    }
}

 


 

3. Mock

  • 특정 메서드가 호출되었는지, 몇 번 호출되었는지 검증하는 행위 기반 테스트
  • 메서드 호출 여부나 횟수 검증에 초점
  • Mockito 기준 verify() 사용
@ExtendWith(MockitoExtension.class)
class UserServiceMockTest {

    @Mock
    UserRepository userRepository;

    @InjectMocks
    UserService userService;

    @Test
    void findUser_ShouldCallRepositoryOnce() {
        User user = new User("testUser", "test@email.com");
        when(userRepository.findByUserId("testUser")).thenReturn(Optional.of(user));

        userService.findUser("testUser");

        // Mock: 해당 메서드가 한 번 호출되었는지 검증
        verify(userRepository, times(1)).findByUserId("testUser");
    }
}

 


 

정리하며

 

  • 단위 테스트는 외부 의존성을 격리한 상태에서 단일 클래스/메서드의 비즈니스 로직을 검증해야 한다.
  • 상태 검증에는 Stub, 호출 행위 검증에는 Mock을 상황에 맞게 사용하는 것이 핵심이다.

 

테스트 더블의 개념을 확실히 잡고 나니, 이전보다 훨씬 빠르고 명확한 단단한 단위 테스트를 작성할 수 있게 되었다.

댓글 남기기