어떤 개념인가요 ?
Mock이란 무엇일까?
Mock은 테스트 대상이 의존하는 객체를 흉내내는 가짜 객체이다.
실제 객체처럼 호출할 수 있지만, 내부 동작은 우리가 미리 정의한 대로만 응답하게 된다.
테스트 더블이라는 큰 범주 안에 Mock, Stub, Fake, Spy, Dummy라는 것이 존재하고, 통틀어서 Mock이라고 부른다.
단위 테스트 작성 시 어디까지 Mock을 적용해야 할까?
먼저 생각해볼 수 있는 부분은 단위 테스트이 경계를 어디까지 설정하고 있을까에 대한 부분입니다.
현재 테스트를 하고자 하는 단위에 대한 생각이 달라서 어디까지 Mock을 적용해야할까에 대한 이야기가 나오는거 같습니다.
그리고 이렇게 테스트의 단위가 다르고 Mock의 적용 범위에 대한 생각을 해본다면, 다음과 같은 트레이드오프가 존재하는거 같습니다.
- Mocking을 너무 많이한다면, 테스트가 빠르고, 예왜 상황 재현이 쉽고, 실패 원인 추적이 쉽지만 ,구현 세부 사항에 종속된 깨지기 쉬운 테스트가 되거나,
- Mocking을 너무 적게 하면, 실제 동작에 가까운 검증이 가능하고, 리팩토링에 강하지만, 테스트가 너무 느려지고, 테스트 간 격리가 어렵고, 외부 환경에 너무 의존하게 되어, 실패 원인이 여러 곳일 가능성이 높아서 디버깅이 어렵게 됩니다.
그럼 우리는 단위 테스트를 어디까지 Mock을 적용해야할까? 에 대한 질문에 답을 해보자면 다음과 같이 정리할 수 있을거 같습니다.
Mock 의존성의 성격으로 나눠본다.
- 외부 API → Mock
- 다른 도메인의 Service → Mock
- 같은 도메인의 객체, VO → 실제 객체
또한, 테스트를 통해 모든 것을 검증하려고 하지 않고, 테스트 피라미드로 역할들을 분담하는 것이 필요하다고 생각합니다.
즉, 단위 테스트, Repository 테스트, 통합 테스트, 엔드투엔드 테스트까지 각 테스트에 책임을 어떻게 지고 있을까에 대한 생각으로 테스트를 작성하는게 중요하다고 생각합니다.
결론은, “Mock을 어디까지 적용해야할까?” 라는 질문보다는 “지금이 테스트 코드의 책임이 무엇인가?”를 생각하며 본질적인 질문으로 접근하는 자세가 필요할거 같습니다.
어떤 문제를 해결하려고 나왔나?
느린 테스트
Mock을 사용하지 않는다면 DB 조회, 외부 API 호출 등은 시간이 많이 걸릴 가능성이 있어 테스트 수천 개를 돌리기 어려울 수 있다.
불안정한 테스트
외부 API에 의존하게 된다면 다운이 되거나 네트워크가 끊기 되면 테스트가 실패할 가능성이 생긴다. 제
제현하기 어려운 상황
예를 들어서 DB 커텍션이 끊긴 경우, API가 타임아웃된든 경우 등 예외 상황을 실제로 만들기 어려운 경우 Mock이 필요하다.
테스트 격리의 어려움
A를 테스트 하려고 하는데 B, C가 모두 같이 동작해야 한다면, 지금 테스트 하려고 한는 것이 A, B, C 중 어떤 것의 버그인지 알기가 어렵다.
어떻게 동작하나? (큰 그림)
언제 쓰고, 언제 안 쓰나?
- 쓸 때:
- 안 쓸 때: