반응형
이 내용은 엘레강트 오브젝트
를 읽으면서 정리한 내용을 포함하고 있습니다.
- 페이크(Fake)
- 한걸음 더 나아가기
- 정리
페이크(Fake)
테스트를 최적화하기 위한 도구인 모킹(Mocking)을 많이 사용하는데, 하지만 모킹 대신 페이크 객체를 사용할 것을 제안한다.
- 페이크 클래스는 인터페이스의 일부이며 인터페이스와 함께 제공한다.
- 페이크 클래스가 실제 클래스보다 더 복잡한 경우도 존재한다.
- 페이크 클래스를 만족하도록 테스트를 작성하지 말고, 페이크 클래스가 테스트를 올바르게 지원하도록 작성한다.
프로덕션 코드 변경 시 단위 테스트 코드를 수정하지 않으면 실패하게 된다.
- 단위 테스트도 신경써서 수정해야 한다.
페이크 클래스가 존재하는 상황에서 해당 인터페이스를 변경하기 위해서는 자연스럽게 해당 인터페이스 클래스의 구현도 함께 변경해야 한다.
- 페이크 클래스를 사용하면 테스트를 충분히 유지보수 가능하게 만들 수 있다.
실습을 통해서 좀 더 자세히 알아보도록 하겠다.
실습 환경
- Java 11
- Spring Boot 2.7.2
- Gradle 7.5
- Database - H2
- MessageQueue - RabbitMq
실습해보기
먼저는 @Mock
을 통해 테스트 코드를 작성하였을때를 알아보도록 하겠다. 회원 서비스인 CustomerService
에서는 회원가입 서비스도 제공하고 있다.
회원가입 시 가입 정보를 처리를 Queue를 통해서 전달한다고 가정해보자.
- Queue의 메세지를 보낼때 만약 메세지 전송의 실패가 발생하면
RuntimeException
으로 감싸는 것이 잘 수행되는지를 테스트 하고 싶다. CustomerService
에서 의존중인 다른 모듈둘에 대해서 회원가입에서는 사용하고 있지 않다. 오직rabbitTemplate
만 사용하고 있다.- CustomeRepository, CustomerOrderRepository, ProductService 등
익숙한 방식인 @Mock
은 다음과 작성해볼 수 있다.
- 보시는 것과 같이 간단하게 작성할 수 있는데, 간단하게 작성할 수 있다는 것이 포인트이다.
- 대상 객체인
CustomerSerice
가 테스트 하기 어려울 정도로 의존성이 결합되어 있지만 아주 간단하게 테스트 코드가 작성된 것이다.
@Mock
이 없이 테스트 코드를 작성한다면 어떻게 작성할 수 있을까?
- 의존해야될 대상이 많다보니 자연스럽게 Mocking 해야할 대상이 너무 많다.
CustomerService
가 의존하고 있는 모든 Bean 들의 MockClass 생성이 필요해서 테스트 코드 작성하기가 정말 힘들다.
테스트 하기 좋은 코드
그럼 테스트 하기 좋은 코드로 될려면 어떻게 바꿔야할까?
- 테스트 대상인
sendMessage
메소드가 의존하고 있는 의존성은 RabbitTemplate 뿐이다. - 그래서 Queue 에 메세지를 보내는 sendMessage를 별도의 컴포넌트로 분리하면 된다.
다음과 같이 변경해볼 수 있다.
- 새로운 서비스인
AmqpMessageSender
를 생성하면서RabbitTemplate
의존성을 가져왔다. - 더 이상 많은 모듈을 의존하지 않고 실제 사용하는 서비스의 모듈만 의존하고 있다.
이전보다 테스트 코드 작성하기가 굉장히 쉬워졌다.
- 분리된 해당 클래스만 테스트 하면 된다.
- 한걸음 더 나아가기
Mock만 사용하지 않는다고 해결이 되는 것은 아니다.
- 테스트 코드를 작성하면서 가장 염려해야될 부분이 프로덕션 코드와 테스트 코드가 같이 움직이지 않는 것이다.
- 그러기 때문에 프로덕션 코드의 내용이 변경된다면 테스트는 실패하게 된다.
- 해당 챕터에서는 Fake 클래스에 대해서 제안하고 있다.
아래와 같이 기존에 구현한 클래스의 인터페이스를 추가하고 Fake inner
클래스를 생성하도록 하겠다.
- 기존 프로덕션 인터페이스의 테스트 코드에서 사용할 동작을 지정한다.
테스트 코드는 다음과 같이 작성할 수 있다.
- 프로덕션 코드가 변경된다면 컴파일 에러를 통해서 같이 수정이 일어나게 된다.
- 프로덕션 코드와 테스트 코드가 같이 움직인다.
정리
- 페이크 클래스가 존재하는 상황에서 해당 인터페이스를 변경하기 위해서는 자연스럽게 해당 인터페이스 클래스의 구현도 함께 변경해야 한다.
- 페이크 클래스를 사용하면 테스트를 충분히 유지보수 가능하게 만들 수 있다.
관련해서 생각해볼 내용
- 운영 인터페이스 코드에 테스트 관련 소스를 내보내는 것이 과연 안전한 방법인가?
반응형
'독서이야기 > 엘레강트 오브젝트 - 새로운 관점에서 바라본 객체지향' 카테고리의 다른 글
[엘레강트 오브젝트] 3.1 5개 이상의 public 메서드만 노출하세요 (0) | 2023.03.12 |
---|---|
[엘레강트 오브젝트] 2.9 인터페이스를 짧게 유지하고 스마트(smart)를 사용하세요 (0) | 2023.03.12 |
[엘레강트 오브젝트] 2.7 문서를 작성하는 대신 테스트를 만드세요 (0) | 2023.03.12 |
[엘레강트 오브젝트] 2.6 불변 객체로 만드세요 (0) | 2023.03.12 |
[엘레강트 오브젝트] 2.5 퍼블릭 상수(Public Constant)를 사용하지 마세요 (0) | 2023.03.12 |
댓글