-
테스트를 위한 Mock과 그 외의 Test DoubleSpring 2022. 2. 3. 18:49
https://dodop-blog.tistory.com/285
https://dodop-blog.tistory.com/287
이전 시간을 통해서 Mockito와 Fake를 이용한 테스트 진행 방식을 알아보았다.
각각 장점을 가지고 있었지만 단점 또한 존재하고 있었다.
Mock과 그 외 TestDouble을 이용한 테스트의 차이를 알아보자.
상태기반의 테스트 ( Test Double ) vs 행위 기반의 테스트 ( Mock )
- 상태 기반의 테스트 : 특정 메서드를 거친 뒤 객체의 상태에 대해 예상값과 비교하는 방식
- 행위 기반의 테스트 : 특정 행위를 수행했는지 확인하는 방식 ( 리턴방식이 void 이거나 예상된 동작을 보장할 수 없을 때)
Mock Object를 이용한 테스트 ( 행위 기반의 테스트 )
Mock은 행위 기반의 테스트로 다음과 같은 경우에 사용된다.
- 테스트 환경 구축에 많은 시간이 소요되거나 환경 모듈 구축이 어려운 경우 (데이터 베이스 연동, 모듈 문제)
- 테스트 시간 단축이 필요한 경우 (네트워크 간 연동 모듈 접속 시간이 오래 걸리는 경우)
- 테스트의 의존성을 단절시켜야 하는 경우
- 타 부서와의 협의 또는 정책이 필요한 경우
- 실제 객체가 비결정적인 행위를 보일 때
- 실제 객체가 UI를 가지고 있거나 그 자체일 때
- 아직 실제 객체가 없을 때
TestDouble(Mock 제외)를 이용한 테스트 (상태 기반의 테스트 )
TestDouble이란 테스트를 수행하기 위해서 실제 컴포넌트 역할을 대체하는 기능을 가진 객체 혹은 컴포넌트를 뜻한다.
Dummy Object 실제 기능이 아닌 인스턴스화된 객체만 사용할 때 (메소드를 사용하지 않아 올바른 기능 구현이 되어 있지 않아도 될 때) Test Stub Dummy의 업그레드버전 (객체 특정상태를 가정하여 만들어 놓은 단순 구현체 = 인스턴스화 + 상태),
메소드 호출시 기본값 반환(로직이 들어간 부분은 테스트 불가)FakeObject 여러개의 인스턴스를 대표하는 경우 또는 구현이 들어가는 경우,
복잡한 구현이 들어간 객체 (실제 구현체와 같은 동작을 하는 객체이지만 프로덕션에서는 사용 불가)Test Spy 테스트에 사용되는 객체에 대해서 호출 여부를 감시하고 요청이 들어오면 보여준다. 각각의 장단점
Test Double 장점 단점 Dummy Object 만들기 매우 쉽다. 용도가 제한적 Test Stub 만들기 쉽다. 단위테스트 결과가 명확하지 않으며, 멤버가 올바르게 호출 되었는지 확인 불가, 유연한 테스트 코드 작성 제한 FakeObject 다양한 시나리오에 사용가능한 완전한 구현 제공 구현하기가 어렵고, Fake Object에 대한 단위 테스트가 필요할 정도의 복잡성을 지닐 수 있음 Test Spy 멤버가 올바르게 호출 되었는지 확인 가능 단위테스트 결과가 명확하지 않으며, 유연한 테스트 코드 작성 제한 Mock Object TestDouble을 효율적으로 만들고 멤버가 올바르게 호출 되었는지 확인 가능, 단위테스트 결과를 명확하게 제공 행위 기반의 테스트는 복잡도나 정확성 등이 상태 기반 테스트 보다 어려운 부분이 많다. 구현부와 결합되어 있을 때 리팩토링에 어려운 점이 있다. 어떤한 것을 사용할 것인가
Mock 과 다른 TestDouble은 setUp 부분( when, given )과 verify 부분에서 다른 TestDouble과는 다르다. 리팩토링에서의 문제 등 때문에 전통적 객체지향을 추구하는 이들은 Fake등의 상태기반 테스트를 주장하고 행위 주도 개발 (Behavior Driven Development)를 주장하는 이들은 Mock객체의 행위기반 테스트( 테스트 케이스 자체가 요구사양이 되도록 개발, 비지니스 요구사항에 집중 )를 주장하기도 한다. 어떤 테스트가 필요할 지 알고 테스트 범위에 따라서 가능한 최소한의 정보로만 테스트가 진행되도록 선택하는 것이 좋다는 의견이 존재한다. ( Dummy -> Stub -> Fake -> Spy or Mock 의 순서 )
나의 경우에는 처음에 Stub 혹은 Fake객체를 이용한 테스트 코드를 작성했지만, Fake객체 구현시 너무 많은 구현이 요구 되었고 이에 대한 단위테스트가 추가로 요구되는 상황과 더불어 delete 메소드의 경우 verify메소드를 통해 행위 검증이 필요했고 반환된 response를 통해 상태 검증도 필요하기 때문에 Mock을 사용하는 방식으로 바꾸었다. 어떠한 것( 상태 또는 행위 )에 집중하여 테스트를 할 것인가에 따라서 테스트마다 Fake나 Mock을 복합적으로 선택할 수 있으니 해당 객체의 장점과 단점을 비교하여 상황에 따라 다르게 적용하는 것이 필요하다.
( 참고한 사이트 ❤️🔥 )
http://egloos.zum.com/kingori/v/4169398
https://uzooin.tistory.com/204
https://happy-coding-day.tistory.com/163
https://d-life93.tistory.com/376
https://codinghack.tistory.com/92
https://brunch.co.kr/@tilltue/55
https://docs.microsoft.com/ko-kr/dotnet/core/testing/unit-testing-best-practices
https://tecoble.techcourse.co.kr/post/2020-09-19-what-is-test-double/
https://ebbnflow.tistory.com/271
https://jesusvalerareales.medium.com/testing-with-test-doubles-7c3abb9eb3f2
https://martinfowler.com/bliki/TestDouble.html
'Spring' 카테고리의 다른 글
existsBy, countBy (JPA) (0) 2022.02.13 인수테스트 (Acceptance Test) ① 환경 구축 및 작성 (0) 2022.02.08 Service Layer의 단위테스트 작성 : (2) Fake 객체 (0) 2022.02.03 Service Layer의 단위테스트 작성 : (1) Mockito ② (0) 2022.02.03 Service Layer의 단위테스트 작성 : (1) Mockito ① (0) 2022.01.28