오해 : Mock을 잘 사용해야 TDD 를 잘할 수 있다.
- “저는 테스트 대역을 거의 사용하지 않습니다” – Kent Beck
- Java의 경우 Mockito를 잘 사용해야 한다는 주장이 있습니다.
- 테스트 환경에서 실제 구성 요소를 대체하는 시스템을 지칭할 때, ‘테스트 대역(test double)’이라는 표현이 더 명확합니다.
- xUnit 테스트 패턴에서 Mock은 테스트 대역의 여러 가지 유형 중 하나입니다.
- 테스트 대역이 유용한 경우가 분명히 있지만, 남용하면 운영 코드와 테스트 간의 정보 공유가 비대해져 설계 변경 비용이 증가하고, 테스트 환경의 가정을 확대해 거짓 음성 가능성이 높아집니다.
- 테스트 대역을 사용하더라도 반드시 별도의 도구가 필요한 것은 아닙니다.
- 본 강의의 실습은 테스트 대역을 거의 사용하지 않습니다.
오해: 테스트를 위해 프로젝트 구조를 설계해야 TDD를 잘할 수 있다
- Java의 경우 패키지 구조를 잘 설계하는 것은 다양한 이점을 있을 수 있지만 테스트에 미치는 영향은 미미합니다.
- 오히려 외부에 드러난 인터페이스 설계와 내부에 감춰진 구현 설계의 명확한 구분이 테스트 작성에 많은 영향을 줍니다.
- 시스템의 적응력을 높이기 위한 아키텍팅의 결과로 모듈이 분리되었다면 자연스럽게 테스트 작성 비용이 낮아지겠지만, 설계 숙련도가 충분하지 않은 채 테스트 용이성만을 목적으로 모듈을 분리하면 오히려 거짓 음성을 야기할 수 있습니다.
오해: 인터페이스 형식을 많이 사용해야 TDD를 잘할 수 있다
- Java 언어의 인터페이스 형식은 운영 코드의 변경과 확장 용이성을 확보하기 위해 사용할 수 있습니다.
- 테스트 작성만을 고려해 인터페이스 형식을 도입한다면 테스트 대상 시스템, SUT(system under test)가 의존하는 구성요소, 실제 DOC(depended-on component)를 추상화해 테스트 환경에서 테스트 대역 사용을 사용하는 것이 유일한 목적입니다.
- 이런 경우 실제 DOC의 행위가 변경되었을 때 테스트 환경에서 테스트와 SUT는 실제 DOC가 아닌 테스트 대역에만 의존하기 때문에 거짓 음성이 발생할 수 있습니다.
- 만약 테스트 환경에서 실제 DOC를 구동하거나 제어할 수 없는 상황이라면 거짓 음성의 위험과 SUT 코드를 테스트하는 효과의 거래도 고려할 만 합니다.
- 해당 문장의 핵심은 “만약 테스트 환경에서 실제로 의존 대상 컴포넌트(DOC: Depend-On Component)를 직접 실행하거나 제어할 수 없다면, 그 컴포넌트를 대체(Stub/Mock)해서 쓰면서 발생할 수 있는 ‘거짓 음성(false negative)’ 위험과, 대신에 SUT(System Under Test: 테스트 대상 코드)를 검증하는 효과 사이에서 적절한 절충을 고민해야 한다”는 뜻입니다.
- 하지만 그렇지 않다면, 테스트 작성만을 위한 인터페이스 형식 도입은 시스템 설계 복잡도를 높이고 테스트 결과 신뢰도를 떨어뜨리는 실수입니다.