Mockito는 정적 메소드를 캡처 할 수 없지만 Mockito 2.14.0 부터 정적 메소드의 호출 인스턴스를 작성하여이를 시뮬레이션 할 수 있습니다.
예 ( 테스트 에서 발췌 ) :
public class StaticMockingExperimentTest extends TestBase {
Foo mock = Mockito.mock(Foo.class);
MockHandler handler = Mockito.mockingDetails(mock).getMockHandler();
Method staticMethod;
InvocationFactory.RealMethodBehavior realMethod = new InvocationFactory.RealMethodBehavior() {
@Override
public Object call() throws Throwable {
return null;
}
};
@Before
public void before() throws Throwable {
staticMethod = Foo.class.getDeclaredMethod("staticMethod", String.class);
}
@Test
public void verify_static_method() throws Throwable {
//register staticMethod call on mock
Invocation invocation = Mockito.framework().getInvocationFactory().createInvocation(mock, withSettings().build(Foo.class), staticMethod, realMethod,
"some arg");
handler.handle(invocation);
//verify staticMethod on mock
//Mockito cannot capture static methods so we will simulate this scenario in 3 steps:
//1. Call standard 'verify' method. Internally, it will add verificationMode to the thread local state.
// Effectively, we indicate to Mockito that right now we are about to verify a method call on this mock.
verify(mock);
//2. Create the invocation instance using the new public API
// Mockito cannot capture static methods but we can create an invocation instance of that static invocation
Invocation verification = Mockito.framework().getInvocationFactory().createInvocation(mock, withSettings().build(Foo.class), staticMethod, realMethod,
"some arg");
//3. Make Mockito handle the static method invocation
// Mockito will find verification mode in thread local state and will try verify the invocation
handler.handle(verification);
//verify zero times, method with different argument
verify(mock, times(0));
Invocation differentArg = Mockito.framework().getInvocationFactory().createInvocation(mock, withSettings().build(Foo.class), staticMethod, realMethod,
"different arg");
handler.handle(differentArg);
}
@Test
public void stubbing_static_method() throws Throwable {
//register staticMethod call on mock
Invocation invocation = Mockito.framework().getInvocationFactory().createInvocation(mock, withSettings().build(Foo.class), staticMethod, realMethod,
"foo");
handler.handle(invocation);
//register stubbing
when(null).thenReturn("hey");
//validate stubbed return value
assertEquals("hey", handler.handle(invocation));
assertEquals("hey", handler.handle(invocation));
//default null value is returned if invoked with different argument
Invocation differentArg = Mockito.framework().getInvocationFactory().createInvocation(mock, withSettings().build(Foo.class), staticMethod, realMethod,
"different arg");
assertEquals(null, handler.handle(differentArg));
}
static class Foo {
private final String arg;
public Foo(String arg) {
this.arg = arg;
}
public static String staticMethod(String arg) {
return "";
}
@Override
public String toString() {
return "foo:" + arg;
}
}
}
그들의 목표는 정적 조롱을 직접 지원하는 것이 아니라 퍼블릭 API를 개선하여 Powermockito 와 같은 다른 라이브러리 가 내부 API에 의존하거나 Mockito 코드를 직접 복제 할 필요가 없도록하는 것입니다. ( 소스 )
면책 조항 : Mockito 팀은 지옥으로가는 길에 정적 방법이 포장되어 있다고 생각합니다. 그러나 Mockito의 임무는 정적 메소드로부터 코드를 보호하는 것이 아닙니다. 팀이 정적 조롱을하는 것을 좋아하지 않는다면 조직에서 Powermockito 사용을 중단하십시오. Mockito는 Java 테스트 작성 방법에 대한 의견을 가진 툴킷으로 진화해야합니다 (예 : 정적을 조롱하지 마십시오 !!!). 그러나 Mockito는 독단적이 아닙니다. 정적 조롱과 같은 권장되지 않는 사용 사례를 차단하고 싶지 않습니다. 우리 일이 아니에요