Static Method를 Mocking 하게 해줘야할까?
깃헙 이슈를 둘러보다가 재미있는 글을 발견했다.
https://github.com/mockito/mockito/issues/1013
해당 이슈는 2017년 3월 Mockito 깃헙에 올라온 이슈로 당시엔 Mockito에서 지원하지 않고 있던 Static Method 모킹 기능을 지원해야할지, 한다면 어떻게 구현할지를 논의하는 글이다.
기존에는 PowerMock과 같은 라이브러리에서 Static Method 모킹을 지원하였으나, 안되는 케이스도 많고 버그도 많았던 것으로 보인다.
코멘트를 보면 알 수 있듯 Static Method 모킹 허용 여부에 대해 개발자들의 찬반이 매우 엇갈린다.
반대파
먼저 Static Method 모킹을 허용해선 안된다의 입장은 다음과 같다.
- Static Method를 모킹하는 것은 안티패턴이다.
- 이를 지원하는 것은 개발자들을 Bad Practice로 이끌 수 있고, 잘못된 코드를 리팩토링하거나 재설계하는 것을 Discourage한다.
- 스터빙이 가능한 별도 클래스로 Static Method를 래핑하는 방식으로 우회하여 모킹이 가능하고 그것이 훨씬 더 바람직한 설계다.
특히나 강경 반대파 중 한 사람은 굉장히 강력한 어조로 아래와 같이 얘기한다.
"내가 StackOverflow에서 PowerMock을 사용한 Static Method 모킹 질문을 많이 봤는데, 하나같이 코드가 엉망이더라. 그걸 왜 모킹하고 있어?" (다소 의역)
역따봉 숫자는 해당 의견을 지지하지 않아서 + 그다지 soft하지 않은 words인 점 모두 반영된 것으로 보인다.
실제로 링크걸린 StackOverFlow 글을 찾아가서 구경을 좀 했는데 하나같이 동일한 어투의 답변을 달아놨더라.
요약하면 그냥 "너가 테스트를 잘못짜고 있는 것 같아"였다. (사실 나도 동일한 의견이긴했다)
말투가 다소 어그레시브해서 거부감이 들긴하지만 그래도 좋은 코드에 대한 열정이 있다는 증거 같아서 개인적으로 이런 사람들을 어려워하면서도 좋아한다.
심지어 스프링 엔지니어링 팀원이더라. 신뢰가 올라가는 대목이긴하다. (그래도 같이 일하기보단 먼 발치에서 바라보고만 싶긴하다)
찬성파
Static Method 모킹 지원에 찬성하는 사람들의 입장은 아래와 같았다.
- 몇 십년된 레거시 코드들에선 Best Practice가 불가한 케이스가 많고 모킹이 불가피한 경우가 분명 있다.
- 당장 JRE의 API만 봐도 환경에 따라 모킹하지 않으면 테스트가 어려운 Static Method가 많다. (주로 파일 관련 API)
- Static Method 모킹이 불가해 테스트가 어려운 코드는 오히려 테스트를 아예 짜지 않게 만들기도 한다.
- Bad Practice를 경계하고 말고는 팀이 고려할 문제이지 라이브러리에서 고려할 사항은 아니다. 쓸 팀을 쓰고 안쓸 팀은 안쓰면 된다.
맨 윗 코멘트의 "Please, consider the legacy code issue"라는 말이 유난히 절실하게 들린다.
Static Method 모킹 자체가 Bad Practice라는 데에는 모두 이견이 없어보이지만 Mockito 라이브러리 자체가 사용자에게 사용 여부에 대해 감놔라 배놔라 할 수는 없다는 것이 주된 입장이었다.
결과는 이미 알다시피 Static Method를 지원하는 방향으로 결정됐다.
해당 이슈가 처음 올라온 것이 2017년인데 무려 3년만에 지원에 대한 합의가 이루어진 것으로 보인다.
그리고 2020년 7월 11일 3.4.0 버전에서 정식으로 기능이 릴리즈되었다.
불과 한 달 전에 올린 코멘트에서 작업할 시간이 없다는 식의 얘기를 했으면서 금방 작업을 해버린 모양이다.
개발과 관련해 많은 것들이 어제는 맞고 오늘은 틀리다.
내일은 더 바람직한 방향으로 나아가는 것에 전적으로 동의하지만, 우리가 이전에 쌓아온 것들이 지금 이 순간 틀리다고해서 돌보지 않을 순 없다.
Mockito 측 또한 비슷한 관점에서의 결정이 아니었을까싶다.
흥미로운 부분은 역시 Static Method 모킹 그 자체의 얘기보단 하나의 신뢰받는 라이브러리가 합의점을 도출해나가며 지원할 기능을 추려나가고 점점 발전해나가는 과정인 것 같다.