테스트 더블, 테스트 대역
모든 유형의 비운영용 가짜 의존성을 포괄하는 용어이다.
더미, 스텁, 스파이, 목, 페이크로 나눌 수 있다.
하지만 크게 보면 크게 목(목, 스파이)과 스텁(스텁, 더미, 페이크) 로 나눌 수 있다.
목
외부로 나가는 상호작용을 모방하고 검사.
목과 스파이
- 목 : 검증 기능을 제공한다.
- 스파이 : 기능적으로 목과 같다. SUT의 간접 출력을 제공하기 위한 대역이다.
스텁
내부로 들어오는 상호작용을 모방. 스텁, 더미, 페이크는 얼마나 똑똑한지에 따라 달라진다.
- 더미는 SUT를 구성하거나 테스트를 실행하는 데 필요하지만, 테스트 하려는 요구사항에는 전혀 영향을 주지 않는 대역이다.
- Stub은 SUT의 간접 입력을 제공하기 위한 대역이다.
- Fake는 실제로 동작하지만, 운영 환경에서 사용하기에는 적합하지 않은 대역을 의미한다.
예시로, 이메일 발송은, SMTP 서버에 사이드 이펙트를 초래하는 상호 작용이다. → 목
반대로, 데이터 검색은 데이터 베이스에서 데이터를 검색하는 것은 내부로 들어오는 상호작용으로 사이드 이펙트를 초래하지 않는다. → 스텁
도구로서의 목과, 테스트 대역으로서의 목
내가 가장 크게 헷갈린 부분이다… mock 클래스를 쓰는 애는 다 테스트 대역으로서의 목인줄 알았다.
하지만 도구로서의 목은 mock 라이브러리에 있는 mock 클래스를 쓰는 것이다.
하지만 테스트 대역으로서의 목은 검증 기능을 갖는, sut 호출을 검사하는 것을 말한다.
예를 들어, 다음과 같이 동일하게 도구로서의 목을 쓰지만, 첫번째는 테스트 대역으로서 목의 역할을 하고, 두번째는 테스트 대역으로서 스텁을 수행한다고 볼 수 있다.
- 테스트 대역 : 목
public void Sending_a_greeting_email(){
// Arrange
var mock = new Mock<IEmailGateWay>();
var sut = new Controller(mock.Object);
// Act
sut.GreetUser("user@email.com");
// Assert
mock.Verift(x-> x.SendGreeintgsEmail(), Times.Once)); // sut의 호출을 검사
}
- 테스트 대역 : stub
public void Creating_a_report(){
// Arrange
var stub = new Mock<IDatabase>();
stub.setup(x=> x.GetNumberOfUsers()).Returns(10);
// Act
var sut = new Controller(stub.Ojbect);
Report report = sut.CreateReport();
// Assert
Assert.Equal(10, report.NumberOfUsers);
}
스텁은 상호 작용을 검증 X
최종 결과가 아닌 사항을 검증하는 경우가 많다 (과잉 명세).
스텁과의 상호 작용을 검증하는 것은 취약한 테스트를 야기하는 일반적인 안티 패턴이다.
목과 스텁이 함께 쓰이면?
테스트 대역이 목이면서 스텁일 수 있다. 목이라는 사실이 스텁이라는 사실보다 더 중요해서 목이라고 대체로 많이한다고 한다.
목과 스텁, 그리고 CQS
- 명령 : 사이드 이펙트를 일으키고, 어떤 값도 반환 X (void 타입) →목
- 조회 : 사이드 이펙트가 없고, 값을 반환. → 스텁
참고 자료
단위테스트 책 그리고 회사 문서
'개발 관련 일지 > TDD' 카테고리의 다른 글
좋은 단위 테스트의 4대 요소 (0) | 2024.02.12 |
---|