[SPRING] Java에서 정적 메서드를 쉽게 조롱 할 수있는 방법 (jUnit4)
SPRINGJava에서 정적 메서드를 쉽게 조롱 할 수있는 방법 (jUnit4)
어떻게하면 Java에서 정적 메서드를 쉽게 조롱 할 수 있습니까?
저는 Spring 2.5와 JUnit 4.4를 사용하고 있습니다.
@Service
public class SomeServiceImpl implements SomeService {
public Object doSomething() {
Logger.getLogger(this.class); //a static method invoked.
// ...
}
}
내 서비스가 호출해야하는 정적 메서드를 제어하지 않기 때문에 더 단위 테스트 할 수있는 리팩터링을 수행 할 수 없습니다. 예를 들어 Log4J Logger를 사용했지만 실제 정적 메서드는 비슷합니다. 정적 메소드를 변경하는 것은 옵션이 아닙니다.
Grails를 사용하면 다음과 같은 것을 사용하는 데 익숙합니다.
def mockedControl = mockFor(Logger)
mockControl.demand.static.getLogger{Class clazz-> … }
…
mockControl.verify()
Java로 비슷한 것을 어떻게하면됩니까?
해결법
-
==============================
1.호출 코드를 제어 할 수 없다는 것을 의미합니까? static 메소드에 대한 호출을 제어하지만 구현 자체는 제어하지 않기 때문에 쉽게 테스트 할 수 있습니다. 정적 메서드와 동일한 서명을 사용하여 단일 메서드로 종속성 인터페이스를 만듭니다. 프로덕션 구현은 정적 메서드로 호출하지만 현재 정적 메서드를 호출하는 것은 인터페이스를 통해 대신 호출합니다.
호출 코드를 제어 할 수 없다는 것을 의미합니까? static 메소드에 대한 호출을 제어하지만 구현 자체는 제어하지 않기 때문에 쉽게 테스트 할 수 있습니다. 정적 메서드와 동일한 서명을 사용하여 단일 메서드로 종속성 인터페이스를 만듭니다. 프로덕션 구현은 정적 메서드로 호출하지만 현재 정적 메서드를 호출하는 것은 인터페이스를 통해 대신 호출합니다.
그런 다음 인터페이스를 정상적인 방법으로 조롱 할 수 있습니다.
-
==============================
2.JMockit 프레임 워크는 정적 메소드의 조롱을 허용합니다.
JMockit 프레임 워크는 정적 메소드의 조롱을 허용합니다.
https://jmockit.dev.java.net/
실제로 정적 메서드가 완벽하게 유효한 디자인 선택이며 테스팅 프레임 워크의 부적절 함으로 인해 해당 메서드의 사용이 제한되어서는 안된다는 등 상당히 과감한 주장이 제기됩니다.
이러한 주장이 정당화 될 수 있는지 여부에 관계없이 JMockit 프레임 워크 자체는 아직 재미 있지는 않지만 아직 직접 시도하지는 않았습니다.
-
==============================
3.PowerMock에는 이러한 기능이 있습니다. 또한 테스트중인 클래스 내부에서 객체의 인스턴스화를 조롱 할 수 있습니다. 테스트 된 메소드가 새 Foo ()를 호출하면 해당 Foo에 대한 mock 객체를 생성하고 테스트중인 메소드에서이를 대체 할 수 있습니다.
PowerMock에는 이러한 기능이 있습니다. 또한 테스트중인 클래스 내부에서 객체의 인스턴스화를 조롱 할 수 있습니다. 테스트 된 메소드가 새 Foo ()를 호출하면 해당 Foo에 대한 mock 객체를 생성하고 테스트중인 메소드에서이를 대체 할 수 있습니다.
억압 생성자와 정적 초기화 자 같은 것들도 가능합니다. 이러한 모든 것은 테스트 할 수없는 코드로 간주되므로 권장되지 않습니다. 그러나 기존 코드가있는 경우 변경하면 항상 옵션이되는 것은 아닙니다. 그 위치에 있다면 PowerMock이 도움이 될 수 있습니다.
-
==============================
4.
public interface LoggerWrapper { public Logger getLogger(Class<?> c); } public class RealLoggerWrapper implements LoggerWrapper { public Logger getLogger(Class<?> c) {return Logger.getLogger(c);} } public class MockLoggerWrapper implements LoggerWrapper { public Logger getLogger(Class<?> c) {return somethingElse;} }
-
==============================
5.위의 또 다른 대답은 JMockit이 정적 메서드를 모의 할 수 있다는 것입니다.
위의 또 다른 대답은 JMockit이 정적 메서드를 모의 할 수 있다는 것입니다.
심지어 로깅 프레임 워크를 직접 지원합니다. 예를 들어 다음과 같이 작성할 수 있습니다.
@UsingMocksAndStubs(Log4jMocks.class) public class SomeServiceTest { // All test methods in this class will have any calls // to the Log4J API automatically stubbed out. }
그러나 JUnit 4.4에 대한 지원은 중단되었습니다. JUnit 3.8, JUnit 4.5+ 및 TestNG 5.8+가 지원됩니다.
-
==============================
6.그것은 정적 방법이 나쁘다는 이유 중 하나입니다.
그것은 정적 방법이 나쁘다는 이유 중 하나입니다.
우리는 대부분의 우리 공장을 재 설계하여 세터 (mter objects)를 설정할 수 있도록합니다. 사실 우리는 하나의 메소드가 모든 싱글 톤을위한 하나의 팩토리로 작동하는 의존성 삽입에 가까운 것을 생각해 냈습니다.
귀하의 경우, Logger.setLogger () 메소드를 추가하고 (해당 값을 저장하는 것) 작동 할 수 있습니다. 필요한 경우 로거 클래스를 확장하고 자신의 getLogger 메서드를 섀도 잉 할 수 있습니다.
-
==============================
7.AspectJ를 사용하여 정적 메소드 호출을 인터셉트하고 테스트에 유용한 것을 할 수있다.
AspectJ를 사용하여 정적 메소드 호출을 인터셉트하고 테스트에 유용한 것을 할 수있다.
-
==============================
8.기본적으로 Java + Spring 2.5 및 JUnit 4.4에서이 작업을 수행하는 쉬운 방법은 없습니다.
기본적으로 Java + Spring 2.5 및 JUnit 4.4에서이 작업을 수행하는 쉬운 방법은 없습니다.
리팩토링하고 정적 호출을 추상화 할 수는 있지만 리팩토링하는 코드는 내가 찾던 솔루션이 아닙니다.
JMockit은 작동하는 것처럼 보이지만 Spring 2.5 및 JUnit 4.4와 호환되지 않습니다.
from https://stackoverflow.com/questions/1203027/how-can-i-easily-mock-out-a-static-method-in-java-junit4 by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 봄 보안, 후행 슬래시 및 URL의 점 (0) | 2019.02.17 |
---|---|
[SPRING] UTF-8 URL 디코드 / 인코딩 (0) | 2019.02.17 |
[SPRING] Apache Tiles의 더 나은 대안 (0) | 2019.02.17 |
[SPRING] java.lang.NoSuchMethodError : org.slf4j.spi.LocationAwareLogger.log (0) | 2019.02.16 |
[SPRING] BeanFactory가 초기화되지 않았거나 이미 닫혔습니다 - 전에 '새로 고침'을 호출하십시오. (0) | 2019.02.16 |