¿Cuál es el mejor marco simulado para Java?

¿Cuál es el mejor marco para crear objetos simulados en Java? ¿Por qué? ¿Cuáles son los pros y los contras de cada marco?

He tenido un buen éxito usando Mockito .

Cuando traté de aprender sobre JMock y EasyMock, encontré que la curva de aprendizaje era un poco abrupta (aunque tal vez solo soy yo).

Me gusta Mockito por su syntax simple y clara que pude comprender bastante rápido. La syntax mínima está diseñada para soportar muy bien los casos comunes, aunque las pocas veces que necesité hacer algo más complicado encontré que lo que quería era compatible y fácil de entender.

Aquí hay un ejemplo (abreviado) de la página de Mockito:

import static org.mockito.Mockito.*; List mockedList = mock(List.class); mockedList.clear(); verify(mockedList).clear(); 

No es mucho más simple que eso.

El único inconveniente importante que puedo pensar es que no se burlará de los métodos estáticos.

¡Soy el creador de PowerMock, así que obviamente debo recomendarlo! 🙂

PowerMock amplía tanto EasyMock como Mockito con la capacidad de simular métodos estáticos , métodos finales e incluso privados. El soporte de EasyMock está completo, pero el plugin de Mockito necesita más trabajo. Estamos planeando agregar compatibilidad con JMock también.

PowerMock no tiene la intención de reemplazar otros marcos, sino que se puede usar en situaciones complicadas cuando otros marcos no permiten la burla. PowerMock también contiene otras funciones útiles, como la supresión de inicializadores estáticos y constructores.

El sitio del proyecto JMockit contiene mucha información comparativa para los kits de herramientas de burla actuales.

En particular, consulte la matriz de comparación de características , que cubre EasyMock, jMock, Mockito, Unitils Mock, PowerMock y, por supuesto, JMockit. Trato de mantenerlo preciso y actualizado, tanto como sea posible.

He estado teniendo éxito con JMockit .

Es bastante nuevo, por lo que es un poco crudo y poco documentado. Utiliza ASM para redefinir dinámicamente el bytecode de clase, por lo que puede simular todos los métodos, incluidos los generadores estáticos, privados, constructores e inicializadores estáticos. Por ejemplo:

 import mockit.Mockit; ... Mockit.redefineMethods(MyClassWithStaticInit.class, MyReplacementClass.class); ... class MyReplacementClass { public void $init() {...} // replace default constructor public static void $clinit{...} // replace static initializer public static void myStatic{...} // replace static method // etc... } 

Tiene una interfaz Expectations que también permite escenarios de grabación / reproducción:

 import mockit.Expectations; import org.testng.annotations.Test; public class ExpecationsTest { private MyClass obj; @Test public void testFoo() { new Expectations(true) { MyClass c; { obj = c; invokeReturning(c.getFoo("foo", false), "bas"); } }; assert "bas".equals(obj.getFoo("foo", false)); Expectations.assertSatisfied(); } public static class MyClass { public String getFoo(String str, boolean bool) { if (bool) { return "foo"; } else { return "bar"; } } } } 

La desventaja es que requiere Java 5/6.

También puedes echar un vistazo a las pruebas usando Groovy. En Groovy puedes simular fácilmente las interfaces Java usando el operador ‘as’:

 def request = [isUserInRole: { roleName -> roleName == "testRole"}] as HttpServletRequest 

Además de esta funcionalidad básica, Groovy ofrece mucho más en el frente mocking, incluidas las potentes clases MockFor y StubFor .

http://docs.codehaus.org/display/GROOVY/Groovy+Mocks

Empecé a usar simulaciones con EasyMock . Lo suficientemente fácil de entender, pero el paso de reproducción fue un poco molesto. Mockito elimina esto, también tiene una syntax más limpia, ya que parece que la legibilidad fue uno de sus objectives principales. No puedo enfatizar lo importante que es esto, ya que la mayoría de los desarrolladores pasarán su tiempo leyendo y manteniendo el código existente, no creándolo.

Otra cosa agradable es que las interfaces y las clases de implementación se manejan de la misma manera, a diferencia de EasyMock, donde aún necesita recordar (y verificar) el uso de una extensión de clase EasyMock.

He echado un vistazo rápido a JMockit recientemente, y si bien la lista de características es bastante exhaustiva, creo que el precio de esto es la legibilidad del código resultante y tener que escribir más.

Para mí, Mockito llega al punto óptimo, es fácil de escribir y leer, y se ocupa de la mayoría de las situaciones que la mayoría de los códigos requerirán. Usar Mockito con PowerMock sería mi elección.

Una cosa a considerar es que la herramienta que elegirías si estuvieras desarrollando por ti mismo, o en un pequeño equipo muy unido, podría no ser la mejor opción para una gran compañía con desarrolladores de diferentes niveles de habilidad. La legibilidad, la facilidad de uso y la simplicidad necesitarían más consideración en este último caso. No tiene sentido obtener el marco de burla definitivo si muchas personas terminan no usándolo o no manteniendo las pruebas.

Estamos utilizando en gran medida EasyMock y EasyMock Class Extension en el trabajo y estamos muy contentos con él. Básicamente te da todo lo que necesitas. Eche un vistazo a la documentación, hay un buen ejemplo que le muestra todas las características de EasyMock.

Usé JMock temprano. Intenté con Mockito en mi último proyecto y me gustó. Más conciso, más limpio. PowerMock cubre todas las necesidades que faltan en Mockito, como burlarse de un código estático, burlarse de una creación de instancia, burlarse de las clases y métodos finales. Entonces tengo todo lo que necesito para realizar mi trabajo.

Me gusta JMock porque puedes establecer expectativas. Esto es totalmente diferente de verificar si se llamó un método encontrado en algunas bibliotecas falsas. Usando JMock puedes escribir expectativas muy sofisticadas. Ver el truco-envoltura jmock .

Sí, Mockito es un gran marco. Lo uso junto con Hamcrest y Google Guice para configurar mis pruebas.

La mejor solución para burlarse es hacer que la máquina haga todo el trabajo con pruebas automatizadas basadas en especificaciones. Para Java, vea ScalaCheck y el marco Reductio incluido en la biblioteca funcional de Java . Con los marcos de prueba basados ​​en especificaciones automatizadas, usted proporciona una especificación del método bajo prueba (una propiedad al respecto que debería ser cierta) y el marco genera pruebas y simulacros de objetos automáticamente.

Por ejemplo, la siguiente propiedad prueba el método Math.sqrt para ver si la raíz cuadrada de cualquier número positivo n al cuadrado es igual a n.

 val propSqrt = forAll { (n: Int) => (n >= 0) ==> scala.Math.sqrt(n*n) == n } 

Cuando llame a propSqrt.check() , ScalaCheck genera cientos de enteros y verifica su propiedad para cada uno, asegurándose también automáticamente de que los bordes estén bien cubiertos.

Aunque ScalaCheck está escrito en Scala y requiere el Comstackdor Scala, es fácil probar el código Java con él. El marco de Reductio en Functional Java es una implementación pura de Java con los mismos conceptos.

Mockito también proporciona la opción de métodos de anotación, haciendo coincidir los argumentos (como anyInt () y anyString ()), verificando el número de invocaciones (times (3), atLeastOnce (), never ()) y más .

También descubrí que Mockito es simple y limpio .

Una cosa que no me gusta de Mockito es que no se pueden cortar métodos estáticos .

Para algo un poco diferente, podrías usar JRuby y Mocha que se combinan en JtestR para escribir pruebas para tu código Java en Ruby expresivo y conciso. Aquí hay algunos ejemplos útiles de burla con JtestR. Una ventaja de este enfoque es que burlarse de las clases concretas es muy sencillo.

Empecé a usar simulaciones a través de JMock, pero finalmente pasé a usar EasyMock. EasyMock era solo eso, más fácil, y proporcionaba una syntax que parecía más natural. No he cambiado desde entonces.