Mockito cannot capture static methods, but since Mockito 2.14.0 you can simulate it by creating invocation instances of static methods.
Example (extracted from their tests):
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(mock);
Invocation verification = Mockito.framework().getInvocationFactory().createInvocation(mock, withSettings().build(Foo.class), staticMethod, realMethod,
"some arg");
handler.handle(verification);
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 {
Invocation invocation = Mockito.framework().getInvocationFactory().createInvocation(mock, withSettings().build(Foo.class), staticMethod, realMethod,
"foo");
handler.handle(invocation);
when(null).thenReturn("hey");
assertEquals("hey", handler.handle(invocation));
assertEquals("hey", handler.handle(invocation));
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;
}
}
}
Their goal is not to directly support static mocking, but to improve its public APIs so that other libraries, like Powermockito, don't have to rely on internal APIs or directly have to duplicate some Mockito code. (source)
Disclaimer: Mockito team thinks that the road to hell is paved with static methods. However, Mockito's job is not to protect your code from static methods. If you don’t like your team doing static mocking, stop using Powermockito in your organization. Mockito needs to evolve as a toolkit with an opinionated vision on how Java tests should be written (e.g. don't mock statics!!!). However, Mockito is not dogmatic. We don't want to block unrecommended use cases like static mocking. It's just not our job.
static
methods, but by accident. This limitation (along with no support for mockingfinal
classes/methods, ornew
-ed objects) is a natural (but unintended) consequence of the approach employed to implement mocking, where new classes are dynamically created that implement/extend the type to be mocked; other mocking libraries use other approaches which avoid these limitations. This happened in the .NET world as well. – Rogério