통합 테스트와 목 모범 사례
- 8.1 통합 테스트의 역할
- 8.2 어떤 외부 의존성을 직접 테스트할까
- 8.3 통합 테스트 모범 사례
- 9.1 목 사용을 비관리 의존성으로 제한하기
- 9.2 스파이와 시스템 경계에서 검증하기
단위 테스트만으로는 충분하지 않아. 각 모듈이 독립적으로는 잘 동작해도, 실제로 함께 엮었을 때 어떻게 되는지는 단위 테스트로 확인하기 어렵거든. 통합 테스트가 필요한 이유야.
통합 테스트는 프로세스 외부 의존성을 포함하는 테스트야. DB, 파일 시스템, 외부 API 같은 것들이 포함돼. 단위 테스트와 통합 테스트는 경쟁이 아니라 보완 관계야. 근데 외부 의존성이라고 해서 다 목으로 대체해야 하는 건 아니야. 여기서 중요한 구분이 나와.
**관리 의존성(Managed dependency)**은 내가 완전히 제어하는 것이야. 우리 팀 DB가 대표적이야. 이건 실제로 써야 해. 목으로 대체하면 진짜 SQL, 제약 조건, 트랜잭션을 검증하지 못하거든. 목이 통과해도 실제 환경에서 터질 수 있어. **비관리 의존성(Unmanaged dependency)**은 외부 팀이나 서비스가 제공하는 거야. 이메일 서버, 외부 결제 API 같은 것들. 이건 목으로 대체해. 실제로 호출하면 사이드 이펙트가 생기거나 느려지거든. 우리 DB는 실제로, 외부 서비스는 목으로. 이 기준이 핵심이야.
통합 테스트를 잘 쓰려면 도메인 모델 경계를 명확하게 하고, 도메인 로직과 인프라 코드를 섞지 말아야 해. 레이어가 많을수록 복잡해지니까 애플리케이션 레이어는 줄이는 게 좋고, 잘못된 상태는 빨리 감지해서 오류가 퍼지기 전에 멈추는 Fail Fast 원칙을 따라야 해.
목을 실제로 쓸 때는 목 프레임워크 대신 **직접 작성한 스파이(spy)**가 더 명시적일 때가 많아. 스파이는 수동으로 만든 목이야. 호출 기록을 컬렉션에 담고 테스트에서 확인하는 방식이지. 프레임워크 특유의 복잡한 설정 없이 바로 읽혀. 그리고 목 검증은 시스템 경계에서 일어나는 호출을 검증해야 해. "이메일이 발송됐는가"가 아니라 **"이 주소로 이 내용이 발송됐는가"**를 확인해야 해. 호출 횟수보다 실제로 무슨 데이터가 전달됐는지가 중요하거든.
정리
6장 읽고 기억할 거 세 가지:
- 관리 의존성(우리 DB)은 실제로 써: 목으로 대체하면 실제 SQL이나 트랜잭션 문제를 못 잡아
- 비관리 의존성(외부 서비스)은 목으로: 실제 호출은 사이드 이펙트와 느린 속도를 불러와
- 시스템 경계에서 무슨 데이터가 나가는지 검증해: 호출 횟수 세는 게 아니라 실제 통신 내용을 봐야 해