•
테스트 대역은 실제 객체를 대신해서 행동하고 실제 객체가 하지 못하는 일을 대신한다.
•
예를 들어, 테스트를 작성하다 보면 어떤 코드는 테스트 단계에서 실제로 실행하기가 부담스러울 수 있다. 또는 테스트하는 데 굳이 실제 객체를 이용해 검증할 필요가 없을 수도 있다. 그럴 때, 테스트 대역을 사용한다.
•
테스트 대역의 장점은 테스트를 위해 격리되고 고정된 환경을 개발자 임의로 설정할 수 있다.
•
다만 테스트 대역을 남용하면 테스트가 점점 실제 구현과 멀어지기 때문에 시스템을 제대로 검증하지 못하는 상황이 발생하곤 한다.
•
테스트 대역의 5가지 유형에는 다음이 존재한다.
유형 | 설명 |
Dummy | 아무런 동작을 하지 않습니다. |
Stub | 지정한 값만 반환합니다. |
Fake | 자체적인 로직이 존재합니다. |
Mock | 아무런 동작을 하지 않는 대신 어떤 행동이 호출되었는지 기록합니다. |
Spy | 실제 객체와 똑같이 동작하며 어떤 행동이 호출되었는지도 기록합니다. |
1. Dummy
•
Dummy는 테스트 대역 중에서도 가장 간단하고 뚜렷한 목적을 가진 대역으로 Dummy의 역할은 아무것도 하지 않는 것이다.
•
Dummy 객체는 오롯이 코드가 정상적으로 돌아가게 하기 위한 역할만 한다. 그리고 특정 행동이 일어나지 않게 만드는데 사용된다.
2. Stub
•
Stub은 미리 준비된 값을 반환하는 대역 객체를 가리킨다. 이 테스트 대역은 Dummy처럼 실제 구현체의 코드를 어느 하나 실행하지 않는다는 점에서 유사하지만 Dummy보단 더 발전된 형태다.
◦
단위 테스트 책에서는 테스트 대상의 연산을 위해 데이터를 제공해주는 역할을 Stub이라고 했던 것 같다.
•
즉, Stub은 미리 준비한 값을 그대로 반환해서 고연산 작업이 실제로 실행되지 않게 한다.
•
당연히 예외 상황을 가정한 응답도 충분히 사용할 수 있다.
3. Fake
•
Fake는 한 단계 더 발전된 유형의 테스트 대역으로 Fake는 테스트를 위한 자체적인 논리를 가지고 있다.
•
이는 로컬 환경의 서버 구성 자체를 변경시킬 수 있다. 즉, 로컬 환경에서 테스트할 때는 Fake 테스트 대역을 사용하도록 만들 수 있다는 의미다.
4. Mock
•
Mock은 번역하면 모조품이라는 의미로 주로 메소드 호출이 발생했는지 여부를 검증하는 역할을 한다.
•
요즘은 Mock이 테스트 대역 모두를 아울러 부르는 것으로 사용되나 엄연히 부분집합이며 그 중에서도 메소드 호출이 발생했는지를 검증하기 위해 만들어지는 테스트 대역에 해당한다.
1. 상태 기반 검증
•
상태 기반 검증은 테스트의 검증 동작에 상태를 사용하는 것을 의미한다.
•
상태 기반 검증으로 동작하는 테스트에서는 테스트를 실행한 후, 테스트 대상의 상태가 어떻게 변경되었는지를 확인하고 테스트 실행 결과를 판단한다.
2. 행위 기반 검증
•
행위 기반 검증은 테스트의 검증 동작에 메소드 호출 여부를 보게 하는 것을 의미한다.
•
즉, 테스트 대상이나 협력 객체, 협력 시스템의 메소드 호출 여부를 검증한다.
3. 상태 기반 vs 행위 기반
•
상태 기반 검증은 시스템의 내부 데이터 상태를 검증하는 테스트인 반면 행위 기반 검증은 시스템의 내/외부 동작을 검증하는 테스트라 할 수 있다.
•
상호 작용 테스트는 그렇게 좋은 전략이 아닌데, 사실상 내부 알고리즘을 테스트하는 것과 같기 때문이다.
•
따라서 상호 작용 테스트가 많아지면 시스템이 전체적으로 정적이게 될 수 있으므로 가급적 상태 기반 검증으로 작성하는 편이 좋다. 그래야 테스트를 책임 단위로 바라볼 수 있게 된다.
5. Spy
•
Spy는 실제 객체 대신 사용되면서 만약 실제 걕체였다면 어떤 메소드가 호출되고 이벤트가 발생하는지 등을 기록하고 감시한다.
•
이런 이유로 Spy는 개념적으로 상호 작용을 검증하는 데 주로 사용된다. 그래서 Mock과 그 역할이 유사하다고 볼 수 있다. 하지만 이 둘에는 결정적인 차이가 있는데, 내부 구현이 진짜 구현체인가 가짜 구현체인가이다.
•
Mock으로 만들어진 객체는 기본적으로 모든 메소드 호출이 Dummy 또는 Stub처럼 동작한다. 반면 Spy로 만들어진 객체는 기본적인 동작이 실제 객체의 코드와 똑같다.
•
즉, 테스트에서 Spy는 기본적으로 실제 객체인 것처럼 동작하지만 실상 내부에서는 테스트를 검증하는 데 필요한 정보를 모으고 있다. 그리고 검증이 필요한 단계에 이를 외부에 알린다.
◦
때문에 프록시 패턴을 이용해 Spy 객체를 만들기도 한다.
6. 정리
•
테스트 대역들이 각각 다른 목적과 동작을 가지고 있으며 테스트 대역은 테스트의 목적과 요구사항에 따라 달리 선택될 수 있다는 것도 알게 됐을 것이다.
◦
더불어 테스트 대역을 만드는데, 굳이 Mock 라이브러리가 필요하지 않음도 확인했다.
•
또한 저자는 테스트 대역을 잘 사용하려면 추상화가 되어있어야 하며 의존성 역전도 잘 적용되어 있어야 한다고 말한다.
•
테스트 가능성을 높이기 위해서는 유연한 설계를 잘 적용해야 한다는 뜻이다. 어느 하나라도 특정 구현에 종속되어 있는 개념은 테스트하는 것이 힘들어진다.