Mockist TDD
Overview
Mockist TDD를 진행해보면서 Mockist TDD의 목표와 추구하는바가 무엇인지에 대한 내용을 기술
Mockist TDD (Solitary Test)
Mockist TDD, often referred to as “Solitary TDD,” advocates for testing each unit of code in isolation. This means that when testing a System Under Test (SUT), any objects that the SUT collaborates with are replaced by test doubles, specifically mocks. These mocks are not just simple stubs that return predefined values; they are configured to expect specific method calls and will fail the test if those calls are not made as expected…
Mockist TDD == TDD 기법의 한종류
Solitary TDD라고도 불림
각 코드의 단위를 격리해 테스트하는것을 지향
SUT 를 대상으로 테스트를 진행할 때 SUT가 의존하는 모든 Collaborators들이 Mocking으로 대체되어 테스트가 진행됨
Glossary
- SUT(System Under Test): 테스트 대상이며, 클래스단위 혹은 메소드단위가 될 수 있음
- Collaborators: 협력 객체, 즉 SUT의 의존성들을 의미
SUT가 서비스클래스를 의미한다면, Collaborators는 해당 클래스가 사용하는 의존성을 의미 (Dao가 될수도, Compoenent가 될수도 있음) - Double: SUT가 의존하는 가짜객체(실제 객체가 아닌)를 통칭 (Double의 종류로 Stub, Fake, Dummy등이 있음)
Advantages
- 설계주도: Mockist TDD는 코드의 설계에 강한 영향을 줌, 의존성을 어떻게 mocking할지 고민하면서 자연스럽게 모듈화되고, 느슨하게 결합되며 테스트하기 쉬운 설계를 하게됨
- 테스트 독립성: 각 테스트는 SUT대상의 동작에만 집중을 요하며 협력 객체의 내부로직에 의존하지 않음 따라서 테스트가 실패하게될 경우 그 원인이 SUT에 있다는것을 알 수 있어 디버깅이 쉬워짐
- 빠른 테스트: 테스트가 실제 외부시스템과 상호작용하지 않기 때문에 테스트를 수월히 할 수 있음
- 상호작용 테스트: SUT가 Collaborator들과 상호작용해야하는 로직을 테스트하는데 수월
Disadvantages
- 변경에 취약(Fragile Tests): SUT의 내부 구현이 변경되는경우, mock 객체에 특정 메소드 호출을 기대하기 때문에 테스트가 실패할 수 있음. 이는 리팩토링시 큰 골칫거리가 될 수 있음
- 테스트설정복잡: mock객체에 대한 기대동작을 설정하는것은 실제 객체를 사요아는 것보다 훨씬 장황하고 복잡할 수 있음 Collaborators가 많거나, 상호작용이 복잡한 클래스일수록 복잡성 증가
- 안정성: 단위테스트가 모두 통과하더라도, SUT와 실제 협력객체간의 통한 문제가 뒤늦게 발견될 수 있음(실제 연계를 하면서) mock이 실제객체의 동작을 완벽히 흉내내지 못하기 때문
When to Use?
-
Collaborator가 테스트 하기 어려울 때: SUT의 협력객체가 데이터베이스, 외부 API 등 실제적으로 테스트 하기 어려울 때 이런 외부협력객체를 Mocking 해버린다면 개발자가 테스트하려고했던 SUT에 대한 고립 테스트가 가능
-
중점이 상태검증 보다 상호작용: 테스트의 포커스가 SUT의 “최종상태”가 아닌, “어떻게 의존성들과 상호작용하는가?”가 중점인 경우에 사용
Conclusion
사용해보면서 Mockist TDD의 핵심 가치는 특정 메소드에대해 고립된 테스트를 실현하는 방식.
복잡한 의존성을 가지고있는 코드에서 상호작용을 하는 로직이 많은경우에 용이
접근법 자체가 결합도를 느슨하게 유도, 결과적으로 보다 유지보수에 이로움
solitary, 진정한 단위의.. 본질..??
이것이 진정한 “단위” 테스트이지 않나..
단위.. 단위 테스트인데 외부 객체에대한 상호작용까지 테스트하는것이 과연 단위인가…
음.. 하지만 SUT가 외부 의존성을 호출하는 부분에 있어
“SUT의 로직이 수행될 때 2번째 라인에서 A의존성과 연계하는데, 어떤값을 이용할것이고,, 어떤값이 응답될꺼다..”
까지의 설정을 진행해야하는데 공수가 적게들진 않음 내부로직이 비교적 잦게 변경되는(?) 개발에는 음..