ONE QUESTION AT A TIME.

천천히 생각하고, 분명하게.

TODAY’S QUESTION406 / 1500
설계난이도 하5분 답변 목표 · 보강본

외부 API를 호출하고 실제 시간을 기다리는 코드의 실패를 테스트하기 어렵습니다. 의존성 주입은 어떻게 도움이 되며 어디까지 적용하나요?

잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?

답변과 점검 포인트 펼치기답변 접기
01

구두 답변

정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.

객체가 외부 시스템을 직접 만들지 않고 필요한 동작을 전달받으면, 테스트에서 시간·네트워크·저장소를 통제하기 쉬워집니다. 중요한 것은 모든 클래스에 인터페이스를 붙이는 것이 아니라 변동하거나 실패하는 경계를 분리하는 것입니다.

의존성 주입은 필요한 상대를 함수나 객체 안에서 직접 만들지 않고 밖에서 전달받는 것입니다. 예를 들어 재시도 함수에 호출 대상과 대기 함수를 전달하면, 테스트에서는 실제 네트워크 대신 ‘첫 호출 실패, 다음 호출 성공’을 반환하고 실제 몇 초를 기다리지 않을 수 있습니다. 이것은 실행을 통제하는 수단이지 가짜 구현이 실제 서버와 같다는 보장은 아닙니다.

재시도 로직을 테스트한다면 실제로 몇 초씩 기다리기보다 시계와 호출 대상을 주입해 첫 실패·두 번째 성공을 재현할 수 있습니다. 저장소도 단순한 CRUD 모양보다 업무가 요구하는 원자적 동작을 인터페이스로 표현하는 편이 좋습니다. 예를 들어 중복 확인과 삽입을 별도 메서드로만 노출하면 가짜 구현은 통과해도 실제 DB의 경쟁을 놓칠 수 있습니다.

저는 순수 계산은 직접 테스트하고, 외부 경계와 비결정적 동작에 주입을 사용하겠습니다. 작은 내부 타입까지 추상화하면 이름과 계층만 늘어 코드를 따라가기 어려워질 수 있습니다. 가짜 구현을 쓰더라도 실제 구현과 같은 계약을 만족하는지 통합 테스트로 확인해야 합니다. 테스트가 빠르다는 것보다 필요한 실패를 재현하고, 생산 환경의 중요한 보장을 가리지 않는지가 기준입니다.

기술 호출보다 정책을 주입합니다

결제나 재시도 로직에 HttpClient 전체를 노출하기보다, 승인 결과·재시도 가능 오류·멱등 키·결과 조회처럼 정책이 판단할 동작을 좁은 계약으로 만듭니다. 시계와 스케줄러를 주입하면 첫 호출 timeout 뒤 두 번째 성공, deadline 만료 뒤 재시도 금지를 실제로 기다리지 않고 재현할 수 있습니다. 저장소도 exists 후 insert를 따로 호출하게 만들면 가짜 구현이 경쟁을 숨길 수 있으므로, 조건부 생성의 성공·중복 결과를 하나의 동작으로 표현하겠습니다.

추상화의 경계를 확인합니다

순수한 금액 계산과 상태 결정은 직접 테스트하고, 시간·네트워크·파일·DB처럼 변동하고 실패하는 경계에만 대역을 둡니다. 목이 호출 횟수만 맞춰도 실제 API가 부분 성공했거나 DB가 원자성을 보장하지 않을 수 있으므로, 실제 구현의 timeout·제약·트랜잭션을 계약·통합 테스트로 확인합니다. 반대로 모든 작은 타입에 인터페이스를 만들면 구현을 찾는 비용이 커집니다. 인터페이스가 SDK 옵션을 그대로 누출하는지, 가짜 구현이 실제보다 강한 보장을 제공하지 않는지를 검토해 주입 범위를 정하겠습니다.

구체적인 경계 사례

조립은 프로그램 시작점 같은 제한된 위치에서 수행합니다. 정책 함수가 서비스 로케이터에서 의존성을 다시 검색하면 생성자에 타입이 있어도 실제 의존성이 숨습니다. 요청별 인증 문맥을 프로세스 전체 공유 객체에 넣으면 다른 요청의 상태가 섞일 수 있으므로 객체별 수명을 명시하고, 풀이나 클라이언트를 누가 닫는지도 조립 시 정합니다.

대역은 상태를 저장하는 간단한 fake, 준비된 응답을 주는 stub, 호출 상호작용을 검사하는 mock처럼 목적이 다릅니다. 결과 계약을 검증할 수 있는 곳에서는 호출 순서까지 과하게 고정하지 않습니다. 반대로 중복 전송 금지처럼 호출 횟수가 실제 외부 계약이면 그 횟수를 검사합니다. 주입은 테스트 수단이고 경계의 의미와 소유권은 설계 결정입니다.

02

득점 포인트

이해가 드러나는 지점을 확인해 보세요.

  • 변동·실패 경계를 정책 중심의 좁은 계약으로 분리한다.
  • 시계·스케줄러·가짜 저장소로 timeout·원자성·멱등 실패를 재현한다.
  • 목 테스트의 한계와 실제 구현의 계약·통합 검증을 함께 제시한다.
03

감점 포인트

놓치기 쉬운 조건과 오해를 짚어 보세요.

  • 모든 타입에 인터페이스를 붙여 구현 탐색과 위임 비용을 키운다.
  • 호출 횟수만 맞으면 실제 API·DB의 원자성과 부분 성공도 같다고 한다.
  • 시계·재시도·외부 효과의 경계를 숨겨 테스트가 환경에 의존하게 만든다.
04

더 파고들 거리

하나 더 질문하며 이해의 범위를 넓혀 보세요.

득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.

원리부터 공부하고 싶다면

답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.

← 전체 질문 보기