2025.04.21 - [기타] - [단위테스트] 원칙과 패턴 (8장) - 통합 테스트를 하는 이유
[단위테스트] 원칙과 패턴 (8장) - 통합 테스트를 하는 이유
소프트웨어의 품질은 코드 그 자체만으로 보장되지 않습니다. 오히려 그것을 둘러싼 테스트 전략과 의존성 관리, 그리고 설계 철학이 품질의 기초를 이룹니다.이번 글에서는 단위 테스트와 통
featherdale.tistory.com
단위 테스트와 통합 테스트를 작성할 때, 목(Mock)의 사용 시점과 대상에 대한 명확한 기준을 세우는 것이 중요합니다. 특히 비관리 의존성(Uncontrolled Dependency) 을 다룰 때는 다음 원칙을 고려해야 합니다.
1. 비관리 의존성이란?
비관리 의존성이란 다음과 같은 외부 시스템을 말합니다:
- 로그 저장소 (Logger)
- 메시지 브로커 (Kafka, RabbitMQ)
- 데이터베이스, 파일 시스템
- REST API 클라이언트
- 인증 서비스 등
개발자가 소스코드를 수정하거나 관찰하기 어려운 외부 시스템이므로, 테스트에서는 직접 통신을 지양하고 대신 "래핑"한 어댑터를 사용하는 것이 바람직합니다.
2. 왜 통합 테스트에서 목을 사용하라고 할까?
목은 비관리 의존성을 다루는 코드의 테스트에만 사용해야 하며, 그 대부분은 통합 테스트에서 이루어진다.
이유 1: 시스템 끝에서의 상호작용 검증
통합 테스트에서는 시스템 경계(예: Controller, Adapter)에서 외부 시스템과 주고받는 데이터를 행위 기반으로 검증해야 합니다.
- 예: Kafka 메시지를 전송했는지 확인
- 예: 외부 API에 POST 요청이 전달되었는지 확인
이런 검증을 위해 목(mock) 을 사용하는 것입니다.
이유 2: 리팩터링 내성 증가
통합 테스트는 전체 경로가 검증되기 때문에, 내부 구현이 변경되어도 실패 확률이 낮습니다. 즉, 목의 사용 위치를 "타입 사슬의 끝단(가장 바깥 Adapter)" 으로 제한하면 내부 변경에 내성이 생깁니다.
3. 단위 테스트에서는 목을 쓰면 안 되나?
단위 테스트에서는 가급적 목을 쓰지 말고, 출력 기반 테스트(결과 검증) 에 집중해야 합니다.
잘못된 예시
when(service.sendNotification()).thenReturn("ok"); // 내부 메서드를 모킹 verify(service).sendNotification(); // 행위 기반 검증
바람직한 예시
String result = sut.doSomething(); assertThat(result).isEqualTo("expectedValue"); // 출력 기반 테스트
4. 스파이(Spy)는 언제 쓰는가?
스파이는 우리가 직접 구현한 목(mock) 객체입니다. 시스템 끝단의 클래스에서 사용하면 다음과 같은 장점이 있습니다:
- 검증 코드의 재사용이 가능해짐
- 테스트의 크기가 줄고 가독성이 향상됨
예: 메시지를 수신한 FakeMessageBus를 만들어 실제 메시지 내용을 확인할 수 있도록 스파이 형태로 구성합니다.
5. 목(Mock) 사용 가이드 요약
| 항목 | 원칙 |
| 대상 의존성 유형 | 비관리 의존성만 목으로 처리 |
| 적용 위치 | 시스템의 가장 바깥, 컨트롤러 or 어댑터 |
| 단위 테스트에서의 목 사용 | 사용 지양 |
| 통합 테스트에서의 목 사용 | 외부 시스템 통신 여부, 메시지 전달 여부 등 검증 시 |
| 메시지 구조 vs 존재 여부 | 메시지 존재만 검증하면 구조 검증 생략 가능 |
| 하위 호환성 유지 | 로깅은 구조 중요치 않음. 메시지 브로커는 중요할 수 있음 |
| 서드파티 라이브러리 접근 시 | 어댑터를 래핑한 타입만 목 처리 |
| 검증문 작성 시 주의 | 제품 코드와 리터럴/상수를 분리하여 테스트 독립 유지 |
6. 결론
- Mock은 어디서나 쓰는 도구가 아니라, 시스템 끝단의 비관리 의존성에 대해 행위 기반 검증이 필요할 때만 사용하는 것이 이상적입니다.
- 단위 테스트에서는 가능한 한 상태 기반/출력 기반 검증만으로 테스트를 구성하고, 내부 구현 세부사항에 의존하지 않도록 주의해야 합니다.
- 코드 리팩터링에 강하고 회귀 방지 효과가 높은 테스트를 만들기 위해, Mock의 위치와 사용 목적을 명확히 하시기 바랍니다.
'기타' 카테고리의 다른 글
| [firebase] 앱 알림 구축 (0) | 2025.08.23 |
|---|---|
| 메모 도구 정리 obsidian vs edrawmind (2) | 2025.08.01 |
| [단위테스트] 원칙과 패턴 (8장) - 통합 테스트를 하는 이유 (0) | 2025.04.21 |
| [단위 테스트] 원칙과 패턴 (7장) - 단위테스트를 위한 리팩터링 (0) | 2025.04.18 |
| [단위 테스트] 원칙과 패턴 (6장) - 단위 테스트 스타일 (0) | 2025.04.17 |
