서비스 테스트는 반드시 Mock 테스트로 해야되나?

PPakSSam·2022년 2월 4일
0
post-thumbnail

@SpringBootTest는 속도가 많이 느리므로 서비스테스트에서는 Mock을 이용하여 테스트하여야 합니다.

서비스 테스트코드 예제에 대한 구글링을 하면 대부분 Mock을 이용한 테스트 코드 예제이며, 속도에 대한 이유로 @SpringBootTest를 사용하지 말라고 나온다.
나 역시 그렇구나 하면서 별 생각없이 Mock을 이용하여 서비스 테스트 코드를 작성하고 있었다.

Mock 테스트 보다는 진짜 협력객체를 사용하는 테스트를 이 수업에서는 추천합니다.

ATDD 2주차 강의에서 브라우니 강사님이 하신 말씀이다.
이유인 즉슨 Mock 테스트는 가짜 객체를 사용하므로 아무래도 프로덕션 코드에 의존하게 되고, 그러면 깨지기 쉬운 테스트가 될 가능성이 높기 때문이었다.

하지만 속도가 중요하다!!! 라고 이미 머리속에 세뇌(?) 당한 나는 이 말을 따르지 않고 서비스 테스트로 Mock 테스트를 작성하며 2주차 미션을 진행하였다.

그런데 말입니다...
패기롭게 Mock 테스트를 작성하던 도중 Mock 테스트인 서비스테스트는 통과하는데 통합테스트인 인수테스트는 통과하지 않는 일이 발생하였다. (?!?!)

뭐지...? 서비스테스트는 통과하는데 인수테스트는 통과하지 않는다고....?
이유를 찾아보니 가짜 객체를 잘못 설계해서 발생한 일이었다.

단순히 속도만 생각하다가는 더 중요한 목적인 검증을 못할 수도 있겠구나...

이 경험은 내게 귀중한 경험이 되었는데 도메인에 대한 지식이 부족하면 가짜 객체를 설계할 때 잘못 설계할 수도 있겠다라는 영감을 얻게 된 계기가 되었다.

도메인 지식이 부족할 때, 처음 테스트를 작성할 때는 통합테스트를 하자

이것이 내가 내린 결론이다. 속도만 생각하여 가짜 객체를 설계하다가 정말 중요한 검증을 못할 수도 있으므로 처음에는 안전하게 통합테스트를 해야겠다는 생각이 들었다.
또한 @SpringBootTest는 모든 빈을 다 띄워서 느리므로 슬라이스 테스트인 @DataJpaTest를 이용하여 통합테스트를 하면 좋겠다라는 의견을 받았고 적극 수용하였다.

그럼 서비스 테스트에서 Mock 테스트는 안 사용할 것인가?

내가 이번에 ATDD 미션을 진행하면서 얻은 귀중한 경험 중 하나는 무조건 이걸 사용해야해! 라는 생각은 위험한 생각임을 인지하게 된 것이다.
같은 맥락으로 서비스 테스트에서 무조건 통합테스트를 할 것인가? 라고 묻는다면 당연히 아니라고 대답할 것이다.

아무래도 통합테스트는 속도가 느리므로 비즈니스 로직은 도메인 영역에서 빡세게 테스트를 하고 정말 필요한 부분만 서비스 테스트에서 통합 테스트로 검증을 할 것이다. 그런데도 불구하고 나중에 프로젝트가 커져서 속도가 정말 느려진다면 그 때는 통합테스트를 Mock 테스트로 바꿔야 할 것이다. 항상 트레이드 오프가 있을 것이고 기회비용을 생각해서 결정해야할 일이다.
사견이지만 통합테스트가 있다는 것은 이미 한번 설계를 했다는 것이고 어느정도 설계지식이 있으니 가짜 객체를 설계할 때 신경써서 한다면 검증오류가 나지 않지 않을까 생각한다.

또한 브라우니 강사님이 Mock 객체를 이용한 테스트를 선택한 경우에 대해 말해주었는데,
미션 현황판에 대한 테스트를 했는데 이에 대한 테스트를 하려면 사전에 해야되는 일이 너무 많았다고 한다. 의존하는 객체가 너무 많아서 일일이 다 넣어주다보면 너무 복잡하므로 그때는 mock을 사용했다고 한다.

우선순위는 통합테스트 > Mock 테스트

내가 내린 결론이다. 일단 통합테스트로 검증을 제대로 하고 그 다음 속도가 이슈가 되면 그 때 Mock 테스트나 Fake 객체 테스트를 고려할 것 같다.

이제 3주차 미션인데 이 때는 다양한 테스트를 해보려고 한다. 통합테스트, Mock 테스트, Fake 객체 테스트 모두 해봐야 겠다.

profile
성장에 대한 경험을 공유하고픈 자발적 경험주의자

0개의 댓글