목에 대해 리팩터링 내성과 회귀 방지를 최대화해서 최대 가치의 통합 테스트를 개발하는 데 도움이 되는 지침을 알아본다.
📖 9.1 목의 가치를 극대화하기
CRM의 통합 테스트를 예제로 사용한다.
- 모든 프로세스 외부 의존성을 거친다.
- 이 테스트는 비관리 의존성을 목으로 처리했다.
🔖 9.1.1 시스템 끝에서 상호 작용 검증하기
시스템 끝에서 상호 작용을 확인하면 회귀 방지가 좋아질 뿐만 아니라 리팩터링 내성도 향상된다.
- 잠재적인 거짓 양성에 노출될 가능성⬇️
- 코드베이스와의 결합도가 낮기 때문에 낮은 수준의 리팩터링에도 영향을 많이 받지 않는다.
비관리 의존성에 대한 호출을 마지막 단계로 선택하라.
- 외부 시스템과의 하위 호환성을 보장
🔖 9.1.2 목을 스파이로 대체하기
스파이
- 목과 같은 목적을 수행하는 테스트 대역
- 목과 달리 수동으로 작성
- 직접 작성한 목이라고도 불림
시스템 끝에 있는 클래스의 경우 스파이가 목보다 낫다
- 검증 단계에서 코드를 재사용해 테스트 크기를 줄이고 가독성을 향상
🔖 9.1.3 IDomainLogger는 어떤가?
로거와 메시지 버스는 비관리 의존성이므로 두 버전 모두 하위 호환성을 유지해야 하지만, 호환성의 정확도가 같을 필요는 없다.
- 메시지 버스를 사용하면 외부 시스템이 이러한 변경에 어떻게 반응하는지 알 수 없으므로 메시지 구조를 변경하지 않는 것이 중요
- 텍스트 로그의 정확한 구조는 Client에게 그다지 중요하지 않다.
📖 9.2 목 처리에 대한 모범 사례
- 통합 테스트에서만 목을 사용하고 단위 테스트에서는 하지 않기
- 항상 목 호출 수 확인하기
- 보유 타입만 목으로 처리하기
🔖 9.2.1 목은 통합 테스트만을 위한 것
도메인 모델
- 복잡도 처리
- 단위 테스트
컨트롤러
- 통신 처리
- 통합 테스트
통합테스트에서 컨트롤러를 테스트할 때만 목을 적용
🔖 9.2.2 테스트당 목이 하나일 필요는 없음
목이 둘 이상인 경우 한 번에 여러 가지를 테스트할 가능성이 있다.
- 단위는 코드 단위가 아니라 동작 단위를 의미
- 동작 단위를 검증하는 데 필요한 목의 수는 관계가 없다.
- 목의 수는 운영에 참여하는 비관리 의존성 수에 의존
🔖 9.2.3 호출 횟수 검증하기
비관리 의존성과의 통신에 관해서 아래 두 가지 모두 확인
- 예상하는 호출이 있는가?
- 예상치 못한 호출은 없는가?
호환성은 양방향이어야 한다.
- 애플리케이션은 외부 시스템이 예상하는 메시지를 생략해서는 안 됨.
- 예상치 못한 메시지도 생성해서는 안됨.
🔖 9.2.4 보유 타입만 목으로 처리하기
서드파티 라이브러리 위에 항상 어댑터를 작성하고 기본 타입 대신 어댑터를 목으로 처리해야 한다.
- 서드파티 코드의 작동 방식에 대해 깊이 이해하지 못하는 경우가 많다.
- 서드파티가 내장 인터페이스를 제공하더라도 목으로 처리한 동작이 실제로 외부 라이브러리와 일치하는지 확인해야하므로 목으로 처리하는건 위험하다.
- 서드파티 코등의 기술 세부 사항까지는 꼭 필요하지 않기에 어댑터는 이를 추상화하고, 애플리케이션 관점에서 라이브러리와의 관계를 정의한다.
실제로 어댑터는 코드와 외부 환경 사이의 손상 방지 계층으로 작동
- 기본 라이브러리의 복잡성 추상화
- 라이브러리에서 필요한 기능만 노출
- 프로젝트 도메인 언어를 사용해 수행
이 지침은 프로세스 내부 의존성에 적용되지 않는다.