모킹이 테스트의 초능력인 이유
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
DevOps
대상자
- 대상자: 소프트웨어 개발자, QA 엔지니어, DevOps 엔지니어
- 난이도: 중급~고급 (단위 테스트, 통합 테스트, CI/CD 파이프라인 경험자)
핵심 요약
- 모킹의 핵심 이점: 외부 의존성 제거로 테스트 속도 80% 향상 및 불확실성 제거
- 핵심 도구:
Mockito
(Java) 및unittest.mock
(Python)을 통해 의존성 시뮬레이션 가능 - 모킹의 3대 원칙:
- Isolation: 외부 시스템과의 분리
- Control: 시나리오별 응답 설정(when(...).thenReturn(...)
)
- Verification: 의존성 호출 검증(verify(mock).method()
)
섹션별 세부 요약
1. 모킹의 정의 및 이점
- 모킹 정의: 외부 의존성(데이터베이스, API 등)을 가상 객체로 대체하여 테스트를 분리
- 주요 이점:
- 속도: 외부 요청(예: HTTP, DB 쿼리) 제거 → 밀리초 단위 테스트 실행
- 안정성: 불안정한 외부 서비스(예: API, 네트워크)로 인한 테스트 실패율 감소
- 유연성: 비정상 시나리오(타임아웃, 잘못된 데이터) 시뮬레이션 가능
2. 모킹의 주요 구성 요소
- Mock: 의존성 행동을 모방하는 가상 객체
- Stub: 사전 정의된 응답 제공 (예:
thenReturn(value)
) - Spy: 실제 객체를 감시하며 일부 행동을 오버라이드
- Verification:
verify(mock).method()
로 호출 횟수 및 파라미터 검증
3. 실무 사례: Sanjay의 테스트 개선
- 문제: 외부 API 의존성으로 인한 테스트 실패율 30%
- 해결:
Mockito
로 의존성 분리 → 테스트 실행 시간 60% 단축, 버그 발견 시간 50% 감소 - 도구 사용:
@Mock
,@InjectMocks
,ArgumentCaptor
활용
4. 모킹 프로세스 흐름
- 의존성 식별:
PaymentApi
인터페이스와 같은 외부 컴포넌트 분석 - 모킹 생성:
Mockito
를 통해PaymentApi
가상 객체 생성 - 행동 설정:
when(...).thenReturn(...)
로 응답 정의 - 테스트 실행: 실제 의존성 대신 모킹 객체 사용
- 호출 검증:
verify(mock).processPayment(...)
로 메서드 호출 검증
5. 실습 예제: Spring Boot + Mockito
- 코드 예시:
```java
@Mock
private PaymentApi paymentApi;
@InjectMocks
private PaymentService paymentService;
@Test
void testSuccessfulPayment() {
when(paymentApi.processPayment("user1", 100.0)).thenReturn(true);
String result = paymentService.initiatePayment("user1", 100.0);
assertEquals("Payment successful", result);
}
```
- 핵심 패턴:
- @Mock
: 의존성 객체 생성
- @InjectMocks
: 테스트 대상에 모킹 객체 주입
- ArgumentCaptor
: 복잡한 파라미터 검증
결론
- 실무 팁:
- 모킹 프레임워크(Mockito
, unittest.mock
) 활용
- 의존성 분리를 통해 CI/CD 파이프라인 안정성 확보
- 예외 시나리오(타임아웃, 잘못된 데이터)를 스텁으로 시뮬레이션
- 핵심 결론: 모킹은 테스트의 속도, 신뢰성, 유연성을 동시에 개선하는 필수 기술이다.