Mockito: cómo simular un método estático con parámetros y tipo de retorno void sin invocar el método real
En otras palabras:
¿Cómo usar “doAnswer” para simular burlas estáticas en mockito?
No encontré una forma de hacerlo. Solo encontré la forma “when(…).then(…)” para simular métodos estáticos.
Por ejemplo:
Quiero linearizar el método SwingUtilities.invokeLater
(¿Por qué? Lo quiero simple :-)).
Usando el último Mockito puedo simular métodos estáticos y escribir algo como esto (en un bloque try-with-resource por supuesto):
Answer<object> directInvocationAnswer = invocation -> {
((Runnable) invocation.getArgument(0)).run();
return null;
};
MockedStatic<swingutilities> mockedStatic = Mockito.mockStatic(SwingUtilities.class, CALLS_REAL_METHODS);
mockedStatic.when(() -> SwingUtilities.invokeLater(any(Runnable.class))).then(directInvocationAnswer);
Funciona, pero puedo ver un NPE en la cola de eventos. No funciona. En absoluto.
Es comprensible, porque () -> SwingUtilities.invokeLater(any(Runnable.class))
invoca realmente SwingUtilities.invokeLater
con null
como parámetro (any()
devuelve null
) y Mockito no puede detener la invocación real, porque no sabe (en este punto en el tiempo) si es una invocación “normal” en el código de producción o una invocación de simulación.
Y no puedo eliminar CALLS_REAL_METHODS
, porque quiero usar otros métodos de la clase.
Sí, puedo engañar a Mockito y evitar llamar a SwingUtilities.invokeLater(null)
:
Answer<object> directInvocationAnswer = invocation -> {
((Runnable) invocation.getArgument(0)).run();
return null;
};
MockedStatic<swingutilities> mockedStatic = Mockito.mockStatic(SwingUtilities.class, CALLS_REAL_METHODS);
any(Runnable.class); // <<<<<<<<<<<<<<<<<<<<<<<<<
mockedStatic.when(() ->
SwingUtilities.invokeLater(MyUtils::nop)) // <<<<<<<<<<<<<<<<<<<<<<<<<
.then(directInvocationAnswer);
return mockedStatic;
Funciona aquí, pero es muy feo y no funciona en todos los casos, el método real se invocó al menos una vez.
¿Existen alguna forma de usar simulaciones similares a doAnswer
para simulaciones estáticas en mockito?
davy.ai
Desafortunadamente, actualmente no existe una forma de utilizar la simulación
doAnswer
para burlar llamadas a métodos estáticos en Mockito. La única opción disponible es utilizarwhen(...).then(...)
para burlar métodos estáticos. Sin embargo, como se demuestra en el ejemplo dado, esto puede llevar a problemas con las NullPointerException (NPE) y la necesidad de llamar aany()
para evitar invocaciones reales de métodos. Hasta que Mockito desarrolle una mejor solución, estamos limitados a estas soluciones temporales.