[XCTest] Test Double (Swift)
## 시작
- sut (system under test): 테스트 대상
- doc (depended-on component): sut이 의존하고 있는 구성요소
테스트 더블이란, doc와 동일한 API를 제공
## 왜 필요할까?
Solitary or Sociable?
테스트 중인 단위가 Sociable한지 혹은 Solitary인지의 여부가 중요하다.
Sociable의 경우에 테스트하는 Unit의 결함이 아닌 의존하고 있는 클래스의 결함으로 인해 테스트가 실패하는 문제가 발생할 수 있다.
이러한 문제를 막기 위해 실제 동작하는 것처럼 보이는 별개의 객체를 따로 만드는 것을 고려할 수 있다.
## 테스트 더블의 종류
- Dummy: 아무런 동작을 하지 않으며, 인스턴스화 된 객체만 필요하고, 기능까지는 필요하지 않은 경우. Dummy의 값은 테스트의 영향을 미치지 않으며, 단순히 객체가 필요할 때 사용. Dummy의 값에 따라 테스트의 결과다 달라진다면 Stub이나 Mock 등을 고려.
: 아무런 행위를 가지지 않는다.
- Fake: 실제로 동작하는 구현을 갖고 있으나, 프로덕션에서 사용되기 적합하지 않은 객체. 구현된 로직은 존재하나 프로덕션 코드에 비해서 매우 단순한 로직으로 제공. Stub과의 차이점은 로직을 처리한다는 것이다.
: DB를 실제 데이터베이스에 의존하지 않고, 배열 등으로 대체해서 구현할 수 있음.
- Stub: Dummy가 마치 실제로 동작하는 것처럼 보이게 만든 객체. 미리 반환할 데이터가 정의되어 있으며, 메소드를 호출하였을 경우 그것을 그대로 반환하는 역할만 수행, Fake와 닮았으나, Fake는 로직을 구현한다면, Stub은 하드코딩된 상태로 값을 내려보낸다. 상태기반 테스트에 사용. Stub은 인풋에 대한 통제권을 가져오는 것이 목적이며, 리턴하는 값에 대한 검증을 신경쓰지 않는다.
: 하드코딩 된, 혹은 미리 구현된 값들이 들어간다.
- Spy: 실제 객체를 부분적으로 Stubbing하면서 동시에 약간의 정보를 기록하는 객체, 기록하는 정보로는 메소드 호출 여부, 메소드 호출 호출 카운트 등이 포함. 기록한다는 특징 때문에 인풋을 검증할 필요가 있을 때 사용.
: 어떠한 메소드가 호출됨으로써 발생할 수 있는 사이드 이펙트를 조사하기 위해 정보를 기록한다는 개념
- Mock: 호출에 대한 기대를 명세할 수 있고, 그 명세에 따라 동작하도록 프로그래밍된 객체. Mock 외의 것은 개발자가 임의로 코드를 생성하여 사용할 수 있음. Mock은 충분히 Dummy, Stub, Spy처럼 동작할 수 있다. 특정 상황에 대해 의존을 해야하는 경우 등 넓은 범위에서 범용적으로 사용할 수 있다.
경계가 모호하다는 생각이 들었는데, 아래 이미지처럼 경계가 딱 나뉜것은 아니다.
## 개인적인 생각과 마무리(or 회고)
사이드 프로젝트가 커지면서 리팩토링을 진행하고자 함.
UIKit, RxSwift, MVVM을 활용해 개발했던 프로젝트를 SwiftUI로 완전한 리팩토링을 진행했었다.
다만, 리팩토링을 하면서 일부 누락된 기능들이 발생했는데, 만약 테스트 코드를 꼼꼼하게 작성해 두었다면 발생하지 않았을 문제라고 생각했다.
ReactorKit, Coordinator와 RxFlow를 학습했고, CleanArchitecture를 온전히 이해하고 적용하려고 노력하고 있다.
프로젝트의 다음 목표는 SwiftUI + Combine 기반으로 CleanArchitecture, TCA, Tuist
그리고 테스트는 Test Double을 활용하여 App단의 테스트 코드를 작성하는 것을 목표로 하고 있다.
SwiftUI를 사용하고 있어서 화면 전환 방식으로는 어떤 것을 적용할지 더 찾아보자.
테스트 코드를 작성하면서, 어떤 것들을 테스트해야 좋은지에 대한 생각을 많이하고 있다.
단일 메소드에 대한 테스트는 수행하는데 특정 플로우에 대해서 테스트 하는건 어떻게 해야할지가 좀 고민이다.
테스트가 실제 코드보다 더 많아지는 느낌을 매우 많이 느끼기 때문에.
(함께 읽어보면 좋은 글)
https://velog.io/@dlsxor21c/iOS%EC%99%80-Test-double
https://martinfowler.com/bliki/UnitTest.html
https://hudi.blog/test-double/