usar titledborder setborder definicion codigo java unit-testing mocking mockito jmockit

setborder - titledborder java



Comparación entre Mockito y JMockit: ¿por qué Mockito es mejor que JMockit? (5)

Para una fácil prueba de nuestra base de código heredada (con muchas llamadas a métodos estáticos, etc.), JMockit ha sido invaluable. [Enchufe desvergonzado para un article en mi blog]

Estoy investigando qué marco de burla usar para mi proyecto y lo he reducido a JMockit y Mockito .

Noté que Mockito fue votado como " el mejor framework falso para Java " en Stackoverflow.
Al comparar las características en la " Matriz de comparación de la herramienta de burla " de JMockit , parece que JMockit tiene múltiples características diferentes.

¿Alguien tiene información específica (no opiniones) sobre lo que Mockito puede hacer que no se puede lograr con JMockit y viceversa?


Personalmente prefiero EasyMock .
La capacidad de desviarse entre los controles de burla agradables, normales y estrictos es uno de mis rasgos favoritos.


Trabajé con Mockito y JMockit, y mi experiencia con ellos es:

  • Mockito:

    • burla implícita (-> mejor usabilidad, pero tiene el peligro de no detectar llamadas de método no permitidas en burlas)
    • verificación explícita
  • EasyMock:

    • explotar burlona
    • verificación implícita
  • JMockit:

    • admite ambos
  • Además, otros beneficios de JMockit:

    • si te estás burlando de los métodos / constructores estáticos, etc. (como extender una base de código heredada muy antigua sin UT), tendrás dos opciones: 1) Mockito / EasyMock con la extensión Powermock o 2) Jmockit
    • informe de cobertura incorporado

Yo personalmente prefiero JMockit, que creo que es más rico en funciones y flexible, pero requiere una curva de aprendizaje un poco más pronunciada. Por lo general, hay varias formas de lograr el mismo efecto de burla y se requiere más cuidado al diseñar los simulacros.


Yo diría que la competencia es entre JMockit y PowerMock , luego Mockito .

Dejaría "simple" jMock y EasyMock porque solo usan proxy y CGLIB y no usan la instrumentación de Java 5 como los frameworks más nuevos.

jMock tampoco tuvo una versión estable por 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 realmente fuera lanzado.

En cuanto a Proxy y CGLIB frente a la instrumentación:

(EasyMock y jMock) se basan en java.lang.reflect.Proxy, que requiere la implementación de una interfaz. Además, admiten la creación de objetos simulados para clases a través de la generación de subclases CGLIB. Debido a eso, dichas clases no pueden ser definitivas y solo se pueden burlar los métodos de instancia invalidables. Lo más importante, sin embargo, al usar 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, para que las instancias simuladas puedan pasarse a los clientes de esas dependencias. Por lo tanto, las dependencias no pueden simplemente crearse una instancia con el nuevo operador en una clase de cliente para la cual 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:

  1. Cada clase que deba ser burlada en una prueba debe implementar una interfaz separada o no ser definitiva.
  2. Las dependencias de cada clase a ser probada deben ser obtenidas a través de métodos configurables de creación de instancias (fábricas o un Localizador de Servicios), o estar expuestas a la inyección de dependencia. De lo contrario, las pruebas unitarias no podrán pasar implementaciones simuladas de dependencias a la unidad bajo prueba.
  3. Dado que solo se pueden burlar métodos de instancia, las clases que se probarán unitarias no pueden invocar ningún método estático en sus dependencias, ni crear instancias de ellos utilizando ninguno de los constructores.

Lo anterior se copia de http://jmockit.org/about.html . Además, se compara entre sí mismo (JMockit), PowerMock y Mockito de varias maneras:

Ahora hay otras herramientas de burla 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 desarrollarse activamente).

JMockit vs PowerMock

  • En primer lugar, PowerMock no proporciona una API completa para la burla, sino que funciona como una extensión de otra herramienta, que actualmente puede ser EasyMock o Mockito. Esto es obviamente una ventaja para los usuarios existentes de esas herramientas.
  • JMockit, por otro lado, proporciona API completamente nuevas, aunque su API principal (Expectativas) es similar tanto a EasyMock como a jMock. Si bien esto crea una curva de aprendizaje más larga, también permite a JMockit proporcionar una API más simple, consistente y fácil de usar.
  • En comparación con la API de JMockit Expectations, la API de PowerMock es más "de bajo nivel", lo que obliga a los usuarios a descubrir 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 con 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 constructor ( expectNew (AClass.class)), simulaciones 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 "sin burlarse" de los miembros sin expectativas grabadas; es decir, el desarrollador simplemente declara algunos "campos simulados" compartidos para la clase de prueba, o algunos "campos simuladores locales" y / o "parámetros ficticios" para métodos de prueba individuales (y en este último caso la anotación @Mocked a menudo no ser necesario).
  • Algunas de las capacidades disponibles en JMockit, como soporte para burking equals y hashCode, métodos reemplazados y otros, actualmente no son compatibles con PowerMock. Además, no existe un equivalente a la capacidad de JMockit para capturar instancias y simular implementaciones de tipos base especificados a medida que se ejecuta la prueba, sin que el código de prueba tenga ningún conocimiento de las clases de implementación reales.
  • PowerMock usa 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 utilizar 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 de 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 manera transparente el agente de Java a pedido utilizando la API de conexión.

Otra herramienta de burla reciente es Mockito. Aunque no intenta superar las limitaciones de las herramientas más antiguas (jMock, EasyMock), introduce un nuevo estilo de prueba de comportamiento con simulacros. JMockit también es compatible con 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 las fases de grabación (cuando (...)) y 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 de burla. Además, esto a menudo generará repeticiones cuando (...) y verifique (simule) ... llamadas.
  • Con JMockit, no existen llamadas similares. Claro, tenemos las nuevas llamadas al constructor NonStrictExpectations () y las nuevas verificaciones (), pero ocurren solo una vez por prueba (típicamente), y están completamente separadas de las invocaciones a los métodos y constructores burlados.
  • La API de Mockito contiene varias incoherencias en la sintaxis utilizada para las invocaciones a los métodos burlados. En la fase de grabación, tenemos llamadas como when (mock.mockedMethod (args)) ... mientras estamos en la fase de verificación, esta misma llamada se escribirá como verify (mock) .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 verify (simulacro).
  • JMockit no tiene tales incoherencias porque las invocaciones a métodos burlados siempre se realizan directamente en las instancias falsas. (Solo con una excepción: para hacer coincidir las invocaciones en la misma instancia simulada, se usa una llamada onInstance (simulada), que da como resultado un código como onInstance (mock) .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 método de encadenamiento / envoltura, Mockito también se encuentra con una sintaxis inconsistente cuando corta métodos vacíos. Por ejemplo, escribe cuándo (mockedList.get (1)). ThenThrow (new RuntimeException ()); para un método no nulo, y doThrow (new RuntimeException ()) when (mockedList) .clear (); para uno vacío. Con JMockit, siempre es la misma sintaxis: mockedList.clear (); result = new RuntimeException () ;.
  • Sin embargo, se produce otra incoherencia en el uso de los espías de Mockito: "simulacros" que permiten que los métodos reales se ejecuten en la instancia espiada. Por ejemplo, si el espía se refiere a una Lista vacía, en lugar de escribir cuándo (spy.get (0)). ThenReturn ("foo"), tendrá que escribir doReturn ("foo"). When (spy) .get ( 0). Con JMockit, la función de burlarse dinámico proporciona una funcionalidad similar a 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 foco estaba totalmente en el registro de invocaciones esperadas de métodos burlados, para objetos falsos que (de forma predeterminada) 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 los simulacros después de que se ejerce el código bajo prueba. Todas estas verificaciones se realizan implícita y automáticamente.
  • En Mockito (y también en Unitil Mock), se toma el punto de vista opuesto. Todas las invocaciones para simular objetos que pueden suceder durante la prueba, ya sea que se graben o no, están permitidas, nunca se esperan. La verificación se realiza de forma explícita después de ejercer el código bajo prueba, nunca automáticamente.
  • Ambos enfoques son demasiado extremos y, en consecuencia, son menos que óptimos. JMockit Expectations & Verifications es la única API que permite al desarrollador elegir a la perfección la mejor combinación de invocaciones simuladas estrictas (esperadas por defecto) y no estrictas (permitidas por defecto) para cada prueba.
  • Para ser más claros, la API de Mockito tiene la siguiente falla. Si necesita verificar que una invocación a un método de imitación no vacío ocurrió durante la prueba, pero la prueba requiere un valor de retorno de ese método que es diferente del valor predeterminado para el tipo de devolución, entonces la prueba de Mockito tendrá un código duplicado: a cuando (mock.someMethod ()). thenReturn (xyz) llama en la fase de registro, y a verify (simulacro) .someMethod () en la fase de verificación. Con JMockit, siempre se puede grabar una expectativa estricta, que no tendrá que ser verificada explícitamente. Alternativamente, se puede especificar una restricción de recuento de invocación (times = 1) para cualquier expectativa no estricta registrada (con Mockito tales restricciones solo se pueden especificar en una llamada de verificación (simulacro, restricción)).
  • Mockito tiene una sintaxis deficiente para las verificaciones en orden y para las verificaciones completas (es decir, verificar que todas las invocaciones a los objetos simulados se verifiquen explícitamente). En el primer caso, se necesita crear un objeto adicional y llamar para verificar en él: InOrder inOrder = inOrder (mock1, mock2, ...). En el segundo caso, se deben realizar llamadas como verifyNoMoreInteractions (mock) o verifyZeroInteractions (mock1, mock2).
  • Con JMockit, simplemente escribe las nuevas VerificationsInOrder () o las FullVerifications () nuevas en lugar de las nuevas verificaciones () (o las nuevas FullVerificationsInOrder () para combinar ambos requisitos). No es necesario especificar qué objetos simulados están involucrados. Sin llamadas API extra burlonas. Y como bonificación, al llamar a unverifiedInvocations () dentro de un bloque de verificación ordenado, puede realizar verificaciones relacionadas con los pedidos 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. También es esencial una herramienta de cobertura de código independiente de IDE, fácil de usar y bien integrada, y eso es lo que JMockit Coverage pretende brindar. Otra pieza del conjunto de herramientas de prueba del desarrollador que se volverá más útil a medida que el conjunto de pruebas crece 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 está incluido en la herramienta Cobertura.

(concedido, la fuente puede estar sesgada, pero bueno ...)

Yo diría que ve con JMockit . Es el más fácil de usar, flexible y funciona en casi todos los casos, incluso en los más difíciles, y en escenarios donde no se puede controlar la clase que se va a probar (o no se puede romper debido a razones de compatibilidad, etc.).

Mis experiencias con JMockit han sido muy positivas.


Yo uso jMockit solo por sus bibliotecas de reflexión en Deencapsultation.class. De hecho, me encanta el estilo de Mockito, pero me niego a cambiar mi código y enturbiar mi API solo para que un marco de prueba limitado pueda lograrlo. Y soy fanático de probar todo mi código, por lo que un framework que no puede probar fácilmente los métodos privados no es lo que quiero usar.

Me dejó influenciado por este artículo

Después de una curva de aprendizaje (ciertamente grande), jMockit es ahora mi marco de pruebas de la unidad principal para los simulacros.