es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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?

Tags:  , , , ,

Answer

  1. Avatar for 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 utilizar when(...).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 a any() para evitar invocaciones reales de métodos. Hasta que Mockito desarrolle una mejor solución, estamos limitados a estas soluciones temporales.

Comments are closed.