저번 포스트에서 LocalDateTime.now()
를 모킹하기 위해 clock
객체를 Bean
으로 등록 후 now()
속 파라미터로 주입했다.
사실, static
메소드를 mocking
하는건 안티패턴이라고 생각한다.
Mockito
깃허브의 Enable mocking static methods in Mockito#1013
이슈에서 관련 논의가 활발하게 진행되었다.
그중 일치하는 의견은 일반적으로
“
static
메소드를mocking
하는건안티패턴
이며, 권장되지 않는다.”
였다.
이에 대한 몇가지 얘기들을 찾아봤다.
내가 보는 정적 모킹의 주요 사용 사례는 다음과 같습니다.
- 레거시 코드(나는 정말로, 정말로 단위 테스트를 작성하고 싶지만 고대의 추악한 코드를 감히 변경할 수 없습니다)
- 일부 어색한 정적 타사 API를 처리합니다. 이 시나리오는 현재 타사 통계 위에 일부 주입 가능한 API 레이어를 개발하여 실행할 수 있습니다. 그러나 해결 방법은 번거롭고 코드베이스의 명확성을 망칠 수 있습니다.
위의 2가지 사용 사례를 다루지 않고 전 세계의 개발자는
Powermockito
등과 같은 도구에서 도움을 찾고 있습니다.정적 모킹 제공의 가장 큰 단점은 정적 메서드로 가득 찬 진부하고 절차적 코드를 테스트하기가 너무 쉽다는 것입니다. 우리는 코드를 깨끗한 OO/DI로 리팩토링하려는 동기를 제거할 것입니다.
Enable mocking static methods in Mockito · Issue #1013 · mockito/mockito
저는 정적 메서드를 광범위하게 사용하고 테스트에 PowerMock(및 PowerMockito)를 많이 사용하는 여러 대규모 코드베이스에서 작업했습니다. 그 당시 내 주요 기억은 테스트 실행이 정말 느리고(어떤 경우에는 PowerMock을 사용하는 테스트가 그렇지 않은 테스트보다 문자 그대로 10배 느림) 궁극적으로 PowerMock의 모든 사용을 제거해야 한다는 것입니다. t 최신 버전의 Java와 호환됩니다. 또한 세부 사항은 더 이상 기억나지 않지만 일부 라이브러리와 호환되지 않아 테스트를 통과하도록 하는 특수 설정이 필요한 것을 기억합니다.
나쁜 코드를 홍보하는 것에 대한 우려를 이해할 수 있지만 Mockito 사용자로서 성능과 견고성에 미치는 영향에 대해 더 걱정할 것입니다. PowerMock을 사용하는 모든 코드가 레거시가 아닙니다. 그 중 일부는 경험이 없는 팀(내가 속해 있던)이 작성한 새로운 코드였으며 Mockito 개발자가 우리의 디자인 패턴을 승인하지 않았다는 사실을 알고 있었다면 별 차이가 없었을 것입니다.
이것은 몇 년 전의 일이며 그 이후로 정적 메서드를 조롱하는 기술이 크게 향상되었을 수 있습니다. 이 기능을 구현하는 강력하고 성능이 좋은 방법이 있다고 생각한다면 환영합니다(사용할 필요가 없기를 바라지만).
Enable mocking static methods in Mockito · Issue #1013 · mockito/mockito
나는 이것에 찢어졌다.(대충 슬프다는 얘기인 듯) 이러한 가능성을 제공하면 개발자를 잘못된 관행에 초대할 수 있습니다. 개발자가 이 기능을 사용할 때마다 그것이 나쁜 습관임을 매우 명시해야 합니다. 이 면에서 명확하면서도 개발자가 동의할 수 있는 솔루션을 제시할 수 있습니까?
Enable mocking static methods in Mockito · Issue #1013 · mockito/mockito
해당 의견은 이슈를 등록했고 Mockito
의 멤버인 mockitoguy 의 의견이다.
나는 우리 모두 정적을 조롱하는 것이 나쁜 습관이며 일반적으로 반패턴이라는 데 동의한다고 생각합니다. 문제는 "정적 조롱 금지" 정책을 시행하는지(예: 도구에서 기능을 제공하지 않음) 또는 사용자가 시행 여부를 결정하도록 하는 것(예: 기능 제공)입니다.
Enable mocking static methods in Mockito · Issue #1013 · mockito/mockito