[java] 왜 Mockito가 정적 메소드를 조롱하지 않습니까?

정적 메소드에 대한 몇 가지 스레드를 읽었으며 정적 메소드의 오용 / 과도한 사용으로 인해 발생할 수있는 문제를 이해한다고 생각합니다. 그러나 정적 메서드를 조롱하기가 어려운 이유는 무엇입니까?

PowerMock과 같은 다른 조롱 프레임 워크가 그렇게 할 수 있지만 왜 Mockito가 할 수 없다는 것을 알고 있습니까?

이 기사를 읽었 지만 저자는 종교적으로 단어에 반대되는 것 같습니다 static. 어쩌면 내 이해력이 떨어질 수도 있습니다.

쉬운 설명 / 링크가 좋을 것입니다.



답변

그 이유는 모의 객체 라이브러리가 일반적으로 런타임에 클래스를 동적으로 생성하여 ( cglib 사용 ) 모의 객체를 생성하기 때문일 수 있습니다 . 즉, 런타임에 인터페이스를 구현하거나 (실수하지 않은 경우 EasyMock 이하는 일) 클래스에서 모의 ​​객체로 상속합니다 (실수하지 않은 경우 Mockito 가하는 일). 상속을 사용하여 재정의 할 수 없으므로 정적 멤버에는 두 가지 방법이 모두 작동하지 않습니다.

정적을 조롱하는 유일한 방법 은 런타임에 클래스의 바이트 코드 를 수정 하는 것입니다. 상속보다 약간 더 복잡하다고 생각합니다.

그게 가치가 있다고 생각합니다.


답변

정적 메서드를 조롱해야하는 경우 나쁜 디자인에 대한 강력한 지표입니다. 일반적으로 테스트 대상 클래스의 종속성을 조롱합니다. 테스트중인 클래스가 java.util.Math # sin과 같은 정적 메소드를 참조하는 경우 테스트중인 클래스가 정확히이 구현이 필요함을 의미합니다 (예 : 정확도 대 속도). 구체적인 부비동 구현을 추상화하려면 인터페이스가 필요할 것입니다 (어디로 향할 것인지 알 수 있습니까).


답변

정적 메서드를 조롱 해야하는 경우 코드 냄새라고 생각합니다.

  • 일반적인 기능에 액세스하는 정적 메소드? -> 싱글 톤 인스턴스를 사용하여 주입
  • 타사 코드? -> 자신의 인터페이스 / 델리게이트로 감싸십시오 (필요한 경우 싱글 톤으로 만드십시오)

이 나에게 잔인한 것 같다 유일한 시간, 구아바 같은 libs와,하지만 당신은 논리의 그것의 일부 (Iterables.transform (같은 것들 ..)) 원인 종류 어쨌든이 조롱 할 필요가 없습니다
그런 식으로 자신의 코드 깨끗하게 유지하고 모든 종속성을 깔끔하게 조롱 할 수 있으며 외부 종속성에 대한 부패 방지 계층이 있습니다. 실제로 PowerMock을 보았고 필요한 모든 클래스가 제대로 설계되지 않았습니다. 또한 때때로 PowerMock의 통합으로 심각한 문제가 발생했습니다
(예 : https://code.google.com/p/powermock/issues/detail?id=355 )

추신 : 개인 메소드도 마찬가지입니다. 테스트가 개인 메소드의 세부 사항에 대해 알아야한다고 생각하지 않습니다. 클래스가 너무 복잡하여 개인 메서드를 모방하려는 유혹이 있다면 아마도 해당 클래스를 분할하는 신호 일 것입니다 …


답변

Mockito는 객체를 반환하지만 정적은 “객체 수준이 아닌 클래스 수준”을 의미하므로 mockito는 정적에 대해 널 포인터 예외를 제공합니다.


답변

경우에 따라 정적 메서드는 특히 조롱해야하는 경우 테스트하기 어려울 수 있으므로 대부분의 조롱 프레임 워크에서 지원하지 않습니다. 블로그 게시물은 정적 메소드와 클래스를 조롱하는 방법을 결정하는 데 매우 유용하다는 것을 알았 습니다.


답변