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

347

¿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?

Josh Brown
fuente

Respuestas:

315

He tenido buen éxito con Mockito .

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

Me gusta Mockito debido a su sintaxis simple y limpia que pude entender bastante rápido. La sintaxis mínima está diseñada para admitir muy bien los casos comunes, aunque las pocas veces que necesitaba 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 inicio de Mockito:

import static org.mockito.Mockito.*;

List mockedList = mock(List.class);
mockedList.clear();
verify(mockedList).clear();

No se vuelve mucho más simple que eso.

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

Brian Laframboise
fuente
15
Hermoso. Para métodos estáticos, simplemente combine Mockito con JMockit y prácticamente no hay clase demasiado "heredada" para que pueda probarla.
Epaga
66
Me encanta cómo cuando intentas hacer algo que no deberías (por ejemplo, crear simulacros en línea), obtienes una explicación muy clara de lo que hiciste mal en el mensaje de excepción.
ripper234
3
Para mi, absolutamente. Todavía lo recomendaría incondicionalmente. Por supuesto, si encuentra otro marco que satisfaga mejor sus necesidades, menciónelo en otra respuesta y vea qué votos obtiene y qué tipo de comentarios recibe.
Brian Laframboise
2
@MexicanHacker, ¿por qué no podrías usarlo para Android? Lo estoy usando ahora, con Robolectric.
Ilkka
2
¡Estoy usando Mockito y me encanta! Gran documentación también (tan raro encontrar documentación de esta calidad, buen trabajo de los autores), que es tan importante para nosotros usar cosas sin tener que profundizar en el código del marco.
Renato
84

Soy el creador de PowerMock, así que obviamente debo recomendarlo. :-)

PowerMock extiende tanto EasyMock como Mockito con la capacidad de burlarse de métodos estáticos , métodos finales e incluso privados. El soporte de EasyMock está completo, pero el complemento Mockito necesita más trabajo. Estamos planeando agregar soporte para JMock también.

PowerMock no está destinado a reemplazar otros marcos, sino que se puede usar en situaciones difíciles cuando otros marcos no permiten la burla. PowerMock también contiene otras características útiles, como la supresión de inicializadores y constructores estáticos .

Jan Kronquist
fuente
Powermock es esencial para probar aplicaciones de Android usando Java nativo en la PC host (evitando usar el emulador lento)
Jeff Axelrod
El único problema de @Jan es que PowerMock es incompatible cuando se utiliza Robolectric :-( Quiero hacer @RunWith (PowerMockRunner.class) Y @RunWith (RobolectricTestRunner.class)
Blundell
Después de usar PowerMock durante los últimos meses, lo recomiendo de todo corazón.
cwash
PowerMock es realmente asombroso. Realmente me encantan los singletons estáticos para acceder a todo, y esto hace que sea posible probarlo.
Ian Macalinao
Advertencia: algunas cosas como burlarse de los métodos finales solo son posibles en Powermock para EasyMock y no para Mockito. Es un poco complicado cuando no lo usas con tanta frecuencia. Me preguntaba por qué algo no funcionaba, entonces me di cuenta de que solo aparece en la sección Easymock del doco.
trafalmadorian
46

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. Intento mantenerlo lo más preciso y actualizado posible.

Rogério
fuente
1
Estoy impresionado por JMockit, tiene una curva de aprendizaje más pronunciada, pero tiene muy buena documentación durante años, y puede burlarse de cualquier cosa. Comencé con Mockito, que era fácil de aprender, pero regularmente encontraba problemas que no podía resolver con él. Por otro lado, ni siquiera puedo imaginar lo que es imposible con JMockit.
Hontvári Levente
21

He tenido é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 la clase, por lo que puede simular todos los métodos, incluidos los 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 Expectativas 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.

Kris Pruden
fuente
Sí, realmente puedo recomendar esto
Epaga
77
Solo una actualización: el proyecto JMockit se trasladó a code.google.com/p/jmockit . Ha evolucionado MUCHO desde esta publicación (y todavía está evolucionando), y ahora tiene una extensa documentación.
Rogério
JMockit se ha movido de nuevo. Ahora está disponible en Github. jmockit.github.io
Ravi Thapliyal
15

También puede echar un vistazo a las pruebas con Groovy. En Groovy, puede burlarse fácilmente de las interfaces de Java utilizando 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 burlón, incluidos los poderosos MockFory las StubForclases.

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

p3t0r
fuente
13

Empecé a usar simulacros con EasyMock . Es bastante fácil de entender, pero el paso de repetición fue un poco molesto. Mockito elimina esto, también tiene una sintaxis más limpia, ya que parece que la legibilidad era uno de sus objetivos principales. No puedo enfatizar lo suficiente lo importante que es esto, ya que la mayoría de los desarrolladores pasarán su tiempo leyendo y manteniendo el código existente, sin crearlo.

Otra cosa buena es que las interfaces y las clases de implementación se manejan de la misma manera, a diferencia de EasyMock, donde aún debe recordar (y verificar) para usar una extensión de clase EasyMock.

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

Para mí, Mockito da en el blanco, siendo fácil de escribir y leer, y lidiando con la mayoría de las situaciones que requerirá la mayoría del código. Usar Mockito con PowerMock sería mi elección.

Una cosa a tener en cuenta es que la herramienta que elegirías si estuvieras desarrollando solo, o en un pequeño equipo muy unido, podría no ser la mejor opción para una gran empresa 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 sin usarlo o no mantienen las pruebas.

trafalmadorian
fuente
1
+1 Esta respuesta necesita más votos a favor. Uno debería compartir lo que realmente les gustó o no del marco. Simplemente "Usé esto ... ¡y me gustó!" Esta es una de las razones por las cuales estas buenas preguntas se cierran en SO.
Ravi Thapliyal
11

Estamos usando EasyMock y EasyMock Class Extension en el trabajo y estamos muy contentos con eso. 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.

dlinsin
fuente
1
En mi pregunta, estaba más buscando lo que te gusta y lo que no te gusta de un marco simulado. Puedo encontrar la documentación y leer todo sobre ella. Quiero saber qué piensan las personas que la han usado.
Josh Brown, el
EasyMock solo funciona en Java 5 y superior, ¡argh!
mate b
8

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

Dmitry
fuente
6

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

Andrea Francia
fuente
5

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

Bartosz Bierkowski
fuente
4

La mejor solución para burlarse es hacer que la máquina haga todo el trabajo con pruebas automatizadas basadas en especificaciones. Para Java, consulte ScalaCheck y el marco Reductio incluido en la biblioteca funcional de Java . Con los marcos de prueba automatizados basados ​​en especificaciones, usted proporciona una especificación del método bajo prueba (una propiedad al respecto que debería ser verdadera) y el marco genera pruebas y objetos simulados, 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 llama propSqrt.check(), ScalaCheck genera cientos de enteros y verifica su propiedad para cada uno, y también se asegura automáticamente de que los casos límite estén bien cubiertos.

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

Apocalipsis
fuente
3

Mockito también ofrece la opción de métodos de apéndice, argumentos coincidentes (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 puede tropezar con métodos estáticos .

Josh Brown
fuente
Esta respuesta es inexacta. No está limitado a interfaces con jMock. Puedes burlarte de clases concretas con el ClassImposteriser.
Teflon Ted
También puede hacer exactamente las mismas cosas con EasyMock.
Cem Catikkas
He eliminado las imprecisiones de mi respuesta.
Josh Brown
2

Para algo un poco diferente, podría usar JRuby y Mocha que se combinan en JtestR para escribir pruebas para su código Java en Ruby expresivo y sucinto. Hay algunos ejemplos útiles con burlones JtestR aquí . Una ventaja de este enfoque es que burlarse de las clases concretas es muy sencillo.

James Mead
fuente
1

Comencé a usar simulacros a través de JMock, pero finalmente hice la transición para usar EasyMock. EasyMock era solo eso, más fácil, y proporcionaba una sintaxis que se sentía más natural. No he cambiado desde entonces.

Mike Furtak
fuente