////
Search
Duplicate

Chapter 14. 테스트 대역

테스트 대역은 실제 객체를 대신해서 행동하고 실제 객체가 하지 못하는 일을 대신한다.
예를 들어, 테스트를 작성하다 보면 어떤 코드는 테스트 단계에서 실제로 실행하기가 부담스러울 수 있다. 또는 테스트하는 데 굳이 실제 객체를 이용해 검증할 필요가 없을 수도 있다. 그럴 때, 테스트 대역을 사용한다.
테스트 대역의 장점은 테스트를 위해 격리되고 고정된 환경을 개발자 임의로 설정할 수 있다.
다만 테스트 대역을 남용하면 테스트가 점점 실제 구현과 멀어지기 때문에 시스템을 제대로 검증하지 못하는 상황이 발생하곤 한다.
테스트 대역의 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 라이브러리가 필요하지 않음도 확인했다.
또한 저자는 테스트 대역을 잘 사용하려면 추상화가 되어있어야 하며 의존성 역전도 잘 적용되어 있어야 한다고 말한다.
테스트 가능성을 높이기 위해서는 유연한 설계를 잘 적용해야 한다는 뜻이다. 어느 하나라도 특정 구현에 종속되어 있는 개념은 테스트하는 것이 힘들어진다.