Actualización de septiembre de 2019: el único marco de simulación compatible (por defecto) con Spring Boot es Mockito . Si usa Spring, la respuesta es bastante obvia.
Yo diría que la competencia es entre JMockit y PowerMock , luego Mockito .
Dejaría jMock y EasyMock "simples" porque usan solo proxy y CGLIB y no usan instrumentación Java 5 como los marcos más nuevos.
jMock tampoco tuvo una versión estable durante más de 4 años. jMock 2.6.0 requirió 2 años para pasar de RC1 a RC2, y luego otros 2 años antes de que se lanzara.
Con respecto a Proxy y CGLIB vs instrumentación:
(EasyMock y jMock) se basan en java.lang.reflect.Proxy, que requiere una interfaz para implementarse. Además, admiten la creación de objetos simulados para clases a través de la generación de subclase CGLIB. Debido a eso, dichas clases no pueden ser finales y solo se pueden burlar los métodos de instancia reemplazables. Sin embargo, lo más importante es que cuando se utilizan estas herramientas, las dependencias del código bajo prueba (es decir, los objetos de otras clases de las que depende una clase determinada bajo prueba) deben ser controladas por las pruebas, de modo que se puedan pasar instancias simuladas a los clientes. de esas dependencias Por lo tanto, las dependencias no pueden simplemente instanciarse con el nuevo operador en una clase de cliente para la que queremos escribir pruebas unitarias.
En última instancia, las limitaciones técnicas de las herramientas de burla convencionales imponen las siguientes restricciones de diseño en el código de producción:
- Cada clase que deba ser burlada en una prueba debe implementar una interfaz separada o no ser final.
- Las dependencias de cada clase a probar deben obtenerse a través de métodos de creación de instancias configurables (fábricas o un Localizador de servicios), o exponerse para la inyección de dependencias. De lo contrario, las pruebas unitarias no podrán pasar implementaciones simuladas de dependencias a la unidad bajo prueba.
- Dado que solo se pueden burlar los métodos de instancia, las clases que se probarán en la unidad no pueden llamar a ningún método estático en sus dependencias, ni instanciarlos usando ninguno de los constructores.
Lo anterior se copia de http://jmockit.org/about.html . Además, se compara entre sí (JMockit), PowerMock y Mockito de varias maneras:
Ahora hay otras herramientas de simulación para Java que también superan las limitaciones de las convencionales, entre ellas PowerMock, jEasyTest y MockInject. El que se acerca más al conjunto de características de JMockit es PowerMock, por lo que lo evaluaré brevemente aquí (además, los otros dos son más limitados y ya no parecen estar desarrollados activamente).
JMockit vs PowerMock
- En primer lugar, PowerMock no proporciona una API completa para burlarse, sino que funciona como una extensión a otra herramienta, que actualmente puede ser EasyMock o Mockito. Obviamente, esto es una ventaja para los usuarios existentes de esas herramientas.
- JMockit, por otro lado, proporciona API completamente nuevas, aunque su API principal (Expectativas) es similar a EasyMock y jMock. Si bien esto crea una curva de aprendizaje más larga, también permite que JMockit proporcione una API más simple, más consistente y más fácil de usar.
- En comparación con la API JMockit Expectations, la API PowerMock es más de "bajo nivel", lo que obliga a los usuarios a determinar y especificar qué clases deben prepararse para la prueba (con la anotación @PrepareForTest ({ClassA.class, ...}) ) y que requieren llamadas API específicas para tratar varios tipos de construcciones de lenguaje que pueden estar presentes en el código de producción: métodos estáticos (mockStatic (ClassA.class)), constructores (suprimir (constructor (ClassXyz.class))), invocaciones de constructores ( expectNew (AClass.class)), simulacros parciales (createPartialMock (ClassX.class, "methodToMock")), etc.
- Con JMockit Expectations, todo tipo de métodos y constructores se burlan de una manera puramente declarativa, con burlas parciales especificadas a través de expresiones regulares en la anotación @Mocked o simplemente "desanimando" a los miembros sin expectativas registradas; es decir, el desarrollador simplemente declara algunos "campos simulados" compartidos para la clase de prueba, o algunos "campos simulados locales" y / o "parámetros simulados" para métodos de prueba individuales (y en este último caso la anotación @Mocked a menudo no lo hará) ser necesario).
- Algunas capacidades disponibles en JMockit, como el soporte para burlarse de iguales y hashCode, métodos anulados y otros, actualmente no son compatibles con PowerMock. Además, no hay equivalente a la capacidad de JMockit para capturar instancias y simulaciones de implementaciones de tipos base específicos a medida que se ejecuta la prueba, sin que el código de la prueba tenga conocimiento de las clases de implementación reales.
- PowerMock utiliza cargadores de clases personalizados (generalmente uno por clase de prueba) para generar versiones modificadas de las clases simuladas. Tal uso intensivo de cargadores de clases personalizados puede generar conflictos con bibliotecas de terceros, de ahí la necesidad de usar a veces la anotación @PowerMockIgnore ("package.to.be.ignored") en las clases de prueba.
- El mecanismo utilizado por JMockit (instrumentación de tiempo de ejecución a través de un "agente Java") es más simple y seguro, aunque requiere pasar un parámetro "-javaagent" a la JVM cuando se desarrolla en JDK 1.5; en JDK 1.6+ (que siempre se puede usar para el desarrollo, incluso si se implementa en una versión anterior) no existe tal requisito, ya que JMockit puede cargar de forma transparente el agente Java a pedido mediante el uso de la API Attach.
Otra herramienta de burla reciente es Mockito. Aunque no intenta superar las limitaciones de las herramientas más antiguas (jMock, EasyMock), sí introduce un nuevo estilo de pruebas de comportamiento con simulacros. JMockit también admite este estilo alternativo, a través de la API de Verificaciones.
JMockit vs Mockito
- Mockito se basa en llamadas explícitas a su API para separar el código entre el registro (cuando (...)) y las fases de verificación (verificación (...)). Esto significa que cualquier invocación a un objeto simulado en el código de prueba también requerirá una llamada a la API simulada. Además, esto a menudo dará lugar a repetitivas cuando (...) y verificar (simulacro) ... llamadas.
- Con JMockit, no existen llamadas similares. Claro, tenemos las nuevas llamadas de constructor NonStrictExpectations () y las nuevas Verificaciones (), pero ocurren solo una vez por prueba (típicamente), y están completamente separadas de las invocaciones a métodos y constructores simulados.
- La API de Mockito contiene varias inconsistencias en la sintaxis utilizada para las invocaciones a los métodos simulados. En la fase de registro, tenemos llamadas como when (mock.mockedMethod (args)) ... mientras que en la fase de verificación, esta misma llamada se escribirá como verificar (simulacro) .mockedMethod (args). Observe que en el primer caso la invocación a mockedMethod se realiza directamente en el objeto simulado, mientras que en el segundo caso se realiza en el objeto devuelto por verificar (simulacro).
- JMockit no tiene tales inconsistencias porque las invocaciones a métodos simulados siempre se hacen directamente en las instancias simuladas. (Solo con una excepción: para hacer coincidir las invocaciones en la misma instancia simulada, se usa una llamada onInstance (simulacro), lo que da como resultado un código como onInstance (simulacro) .mockedMethod (args); sin embargo, la mayoría de las pruebas no necesitarán usar esto. )
- Al igual que otras herramientas de burla que se basan en el encadenamiento / ajuste de métodos, Mockito también se encuentra con una sintaxis inconsistente al tropezar con métodos vacíos. Por ejemplo, escribe cuando (mockedList.get (1)). ThenThrow (new RuntimeException ()); para un método no nulo y doThrow (new RuntimeException ()). when (mockedList) .clear (); para un vacío Con JMockit, siempre es la misma sintaxis: mockedList.clear (); resultado = nueva RuntimeException () ;.
- Otra inconsistencia ocurre en el uso de espías Mockito: "simulacros" que permiten que los métodos reales se ejecuten en la instancia espía. Por ejemplo, si el espía se refiere a una Lista vacía, en lugar de escribir cuándo (spy.get (0)). ThenReturn ("foo") deberá escribir doReturn ("foo"). When (spy) .get ( 0). Con JMockit, la función de burla dinámica proporciona una funcionalidad similar a la de los espías, pero sin este problema, ya que los métodos reales solo se ejecutan durante la fase de reproducción.
- En EasyMock y jMock, las primeras API de simulación para Java, el enfoque se centraba completamente en la grabación de invocaciones esperadas de métodos simulados, para objetos simulados que (por defecto) no permiten invocaciones inesperadas. Esas API también proporcionan el registro de invocaciones permitidas para objetos simulados que permiten invocaciones inesperadas, pero esto se trató como una característica de segunda clase. Además, con estas herramientas no hay forma de verificar explícitamente las invocaciones a simulacros después de ejercer el código bajo prueba. Todas estas verificaciones se realizan implícita y automáticamente.
- En Mockito (y también en Unitils Mock), se toma el punto de vista opuesto. Todas las invocaciones para burlarse de los objetos que pueden ocurrir durante la prueba, ya sean grabadas o no, están permitidas, nunca se esperan. La verificación se realiza explícitamente después de ejercer el código bajo prueba, nunca automáticamente.
- Ambos enfoques son demasiado extremos y, en consecuencia, menos que óptimos. JMockit Expectations & Verifications es la única API que permite al desarrollador elegir sin problemas la mejor combinación de invocaciones simuladas estrictas (esperadas por defecto) y no estrictas (permitidas por defecto) para cada prueba.
- Para ser más claro, la API de Mockito tiene la siguiente deficiencia. Si necesita verificar que una invocación a un método simulado no vacío ocurrió durante la prueba, pero la prueba requiere un valor de retorno de ese método que sea diferente del predeterminado para el tipo de retorno, entonces la prueba de Mockito tendrá un código duplicado: una llamada a (mock.someMethod ()). thenReturn (xyz) en la fase de registro, y una verificación (simulacro) .someMethod () en la fase de verificación. Con JMockit, siempre se puede registrar una expectativa estricta, que no tendrá que verificarse explícitamente. Alternativamente, se puede especificar una restricción de recuento de invocación (veces = 1) para cualquier expectativa no estricta registrada (con Mockito, tales restricciones solo se pueden especificar en una llamada de verificación (simulación, restricción).
- Mockito tiene una sintaxis pobre para las verificaciones en orden y para verificaciones completas (es decir, verificar que todas las invocaciones para simular objetos se verifiquen explícitamente). En el primer caso, se debe crear un objeto adicional y se deben realizar llamadas para verificarlo: InOrder inOrder = inOrder (mock1, mock2, ...). En el segundo caso, se deben realizar llamadas como generate_MoreInteractions (simulacro) o VerifiedInterractions_Cero (simulacro1, simulacro2).
- Con JMockit, simplemente escribe nuevas VerificationsInOrder () o nuevas FullVerifications () en lugar de nuevas Verifications () (o nuevas FullVerificationsInOrder () para combinar ambos requisitos). No es necesario especificar qué objetos simulados están involucrados. No hay llamadas API extra de burla. Y como beneficio adicional, al llamar a unverifiedInvocations () dentro de un bloque de verificación ordenado, puede realizar verificaciones relacionadas con el pedido que son simplemente imposibles en Mockito.
Finalmente, JMockit Testing Toolkit tiene un alcance más amplio y objetivos más ambiciosos que otros kits de herramientas de burla, con el fin de proporcionar una solución de prueba de desarrollador completa y sofisticada. Una buena API para burlarse, incluso sin limitaciones artificiales, no es suficiente para la creación productiva de pruebas. Una herramienta de Cobertura de Código bien integrada, fácil de usar y bien integrada por IDE también es esencial, y eso es lo que JMockit Coverage pretende proporcionar. Otra parte del conjunto de herramientas de prueba para desarrolladores que será más útil a medida que el conjunto de pruebas crezca en tamaño es la capacidad de volver a ejecutar las pruebas de forma incremental después de un cambio localizado en el código de producción; Esto también se incluye en la herramienta Cobertura.
(concedido, la fuente puede estar sesgada, pero bueno ...)
Yo diría que vayas con JMockit . Es el más fácil de usar, flexible y funciona para casi todos los casos, incluso los difíciles y los escenarios en los que no puede controlar la clase que se probará (o no puede romperla debido a razones de compatibilidad, etc.).
Mis experiencias con JMockit han sido muy positivas.