Diferencia entre revisiones de «Mockito»

De Dos Ideas.
Saltar a: navegación, buscar
(GKDorcaBtDCpsMFwVFD)
Línea 1: Línea 1:
Mockito es una librería [[Java]] para la creación de [[Mock Object]] muy usados para el testeo unitario en [[Test Driven Development]], basado en [[EasyMock]].
+
I'm relaly into it, thanks for this great stuff!
 
 
Mockito fue creado con el objetivo de simplificar y solucionar algunos de los temas antes mencionados. EasyMock y Mockito puede hacer exactamente las mismas cosas, pero Mockito tiene un API más natural y práctico de usar.
 
 
 
==Características principales==
 
# Se pueden crear mocks de interfaces y clases concretas.
 
# Verificación de invocaciones (cantidad exacta, al menos una vez, órden de invocación, etc.)
 
# El stack trace se mantiene limpio, ya que los errores ocurren en los assert que se hagan (y no dentro del método bajo prueba, como en EasyMock).
 
# Un API más clara para crear stubs y verificaciones
 
 
 
==Ejemplo de uso==
 
<code java>
 
import static org.mockito.Mockito.*;
 
.....
 
//creamos el mock y el stub
 
ArrayList instance = mock(ArrayList.class);
 
doReturn("hola mundo").when(instance).get(0);
 
 
//ejecutamos la lógica a probar
 
instance.get(0);   
 
 
//verificamos que se hayan invocado los métodos
 
verify(instance).get(0);
 
</code>
 
 
 
==Más de una invocación a un mismo método==
 
 
 
Algunas veces necesitamos que un método retorne un valor y que en la segunda invocación retorne nulo o una excepción. Para eso, anidamos los retornos:
 
 
 
<code html4strict>
 
 
 
//Retornos para las 2 invocaciones
 
doReturn("algo").doReturn(null).when(instance).scrollNext();
 
 
 
//ejecutamos la lógica a probar
 
instance.unMetodoQueUsaScroll();   
 
 
 
//verificamos que se haya invocado el mismo método dos veces
 
verify(instance, times(2)).scrollNext();
 
 
 
</code>
 
 
 
* [http://mockito.googlecode.com/svn/branches/1.5/javadoc/org/mockito/Mockito.html Leer más en Mockito API]
 
 
 
==Ejemplos de Mockito junto a PowerMock==
 
 
 
===Invocación a un método estático===
 
 
 
Para mockear métodos estáticos, según el [http://code.google.com/p/mockito/wiki/FAQ FAQ] de mockito, esto no es posible. Pero nombra 2 framewors que pueden resultarnos útil [http://jmockit.dev.java.net/ JMockit] y [http://code.google.com/p/powermock PowerMock]
 
 
 
<code java>
 
@RunWith(PowerMockRunner.class)
 
@PrepareForTest(ClaseConMetodosEstaticos.class)
 
public class DosIdeasTestCase {
 
    @Test
 
    public void testMetodo_conInvocacionAMetodosEstaticos() {
 
 
        //PowerMockito mockea los metodos estaticos que se encuentren en la
 
        //clase ClaseConMetodosEstaticos
 
        PowerMockito.mockStatic(ClaseConMetodosEstaticos.class);
 
 
 
        //Con mockito determinamos el retorno del metodo estatico
 
        when(ClaseConMetodosEstaticos.firstStaticMethod(param)).thenReturn(value);
 
 
 
        // ejecucion
 
        instance.invocarMetodoEstatico();
 
 
 
        //Por cada metodo estatico que se quiere verificar se debe invocar
 
        //a PowerMockito.verifyStatic().
 
        PowerMockito.verifyStatic();
 
        ClaseConMetodosEstaticos.secondStaticMethod();
 
    }
 
}
 
</code>
 
 
 
===Invocación a un método privado===
 
 
 
<code java>
 
public class PruebaMetodoPrivado {
 
 
 
    public String decirHola(String nombre) {
 
        return decirHolaNombre(nombre);
 
    }
 
 
 
    private String decirHolaNombre(String nombre) {
 
        return "Hola "+nombre;
 
    }
 
}
 
</code>
 
 
 
<code java>
 
@RunWith(PowerMockRunner.class)
 
@PrepareForTest(PruebaMetodoPrivado.class)
 
public class PruebaMetodoPrivadoTest {
 
 
 
  @Spy
 
  PruebaMetodoPrivado metodoPrivado = new PruebaMetodoPrivado();
 
   
 
    @Test
 
    public void mockMetodoPrivado() throws Exception {
 
 
 
Assert.assertEquals("Hola Juan", metodoPrivado.decirHola("Juan"));
 
        doReturn("Chau Juan").when(metodoPrivado,"decirHolaNombre","Juan");
 
        Assert.assertEquals("Chau Juan",metodoPrivado.decirHola("Juan"));
 
        verifyPrivate(metodoPrivado,
 
                      Mockito.times(2)).invoke("decirHolaNombre","Juan");
 
    }
 
}
 
 
 
</code>
 
 
 
===Inicialización de atributos estaticos===
 
 
 
<code java>
 
public class PruebaInicializacionEstaticos {
 
 
 
    private static final String atributo = new String("CHAU");
 
 
    public String crearObjetoLista() {
 
        return atributo;
 
    }
 
}
 
</code>
 
 
 
<code java>
 
@RunWith(PowerMockRunner.class)
 
@SuppressStaticInitializationFor("PruebaInicializacionEstaticos")
 
@PrepareForTest(PruebaInicializacionEstaticos.class)
 
public class PruebaMetodoPrivadoTest {
 
 
 
 
  PruebaInicializacionEstaticos pruebaInicializacionEstaticos =
 
                                    new PruebaInicializacionEstaticos();
 
 
    @Test
 
    public void controlCreacionLista() throws Exception {
 
Assert.assertNull(pruebaInicializacionEstaticos.retornarAtrinbuto());
 
        String s = "Hola";
 
        Whitebox.setInternalState(pruebaInicializacionEstaticos.class,"atributo", s);
 
        Assert.assertEquals(s, pruebaInicializacionEstaticos.retornarAtrinbuto());
 
    }
 
}
 
</code>
 
 
 
===Captura creación de objetos===
 
 
 
<code java>
 
public class PruebaCreacionObjeto {
 
 
    public List crearObjetoLista() {
 
        return new ArrayList();
 
    }
 
}
 
</code>
 
 
 
<code java>
 
@RunWith(PowerMockRunner.class)
 
@PrepareForTest(PruebaCreacionObjeto.class)
 
public class PruebaMetodoPrivadoTest {
 
 
  @Spy
 
  PruebaCreacionObjeto pruebaCreacionObjeto = new PruebaCreacionObjeto();
 
 
    @Test
 
    public void controlCreacionLista() throws Exception {
 
        List list = new ArrayList();
 
        list.add("Hola");
 
        whenNew(ArrayList.class).withNoArguments().thenReturn((ArrayList) list);
 
        List resultado = pruebaCreacionObjeto.crearObjetoLista();
 
        Assert.assertEquals(list, resultado);
 
        verifyNew(ArrayList.class);
 
    }
 
}
 
</code>
 
 
 
Para mas ejemplos de Mockito junto a PowerMock ver los [http://code.google.com/p/powermock/wiki/MockitoUsage13 ejemplos] provisto por la documentación de PowerMock.
 
 
 
[http://www.dosideas.com/descargas/category/3-testing.html?download=40 Descargar proyecto NetBeans demo de los ejemplos]
 
 
 
===PowerMockito & Cobertura===
 
Existe un problema al utilizar PowerMockito con Cobertura (versión 1.8.4), este último no registra la corrida de los test con anotación @PrepareForTest, dando como resultados falta de cobertura.
 
Para solucionar este inconveniente solo hay que actualizar la versión de Cobertura.
 
 
 
==Ejemplo de Mockito para mockear appender de log4j==
 
 
 
<code java>
 
//Inicializamos mock.
 
Appender mockAppender = mock(AppenderSkeleton.class);
 
//Inicializamos logger de la clase bajo test
 
Logger log = Logger.getLogger(ClaseATestear.class);
 
//Agregamos el mock del appender al logger.
 
log.addAppender(mockAppender);
 
//Seteamos el nivel de log que nos interesa recuperar.
 
log.setLevel(Level.DEBUG);
 
</code>
 
 
 
Para poder obtener los log que se produjeron utilizamos la clase ArgumentCaptor de mockito que nos permite, entre otras cosas, capturar los eventos de log.
 
 
 
<code java>
 
ArgumentCaptor loggingEventCaptor = ArgumentCaptor.forClass(LoggingEvent.class);
 
 
 
loggingEventCaptor.capture());
 
</code>
 
 
 
Una posible forma de obtener un mensaje particular es iterando la lista de mensajes que nos da la clase capturada.
 
 
 
<code java>
 
List<LoggingEvent> loggingEvent = (List<LoggingEvent>) loggingEventCaptor.getAllValues();
 
</code>
 
 
 
== BDDMockito ==
 
BDDMokcito es una clase alternativa que ofrece [[Mockito]] para crear pruebas al estilo [[Behavior Driven Development]] (BDD) (es decir, con bloques dado / cuando / entonces).
 
 
 
El problema es que el API de Mockito usa la palabra "when" y no se integra bien con los comentarios //given //when //then (según BDD, el stubbing forma parte del área //given, y no del //when).
 
 
 
BDDMockito agrega una clase que tiene alias para los métodos de stub, usando given(Object).
 
 
 
<code java5>
 
import static org.mockito.BDDMockito.*;
 
 
Vendedor vendedor = mock(Vendedor.class);
 
Negocio negocio = new Negocio(vendedor);
 
 
@Test
 
public void comprarPan() throws Exception {
 
  //given 
 
  given(vendedor.buscarPan()).willReturn(new Pan());
 
 
 
  //when
 
  Compra compra = negocio.comprarPan();
 
 
 
  //then
 
  assertThat(compra, contienePan());
 
}
 
</code>
 
 
 
Stubbing con void y excepciones:
 
<code java5>
 
  //given
 
  willThrow(new RuntimeException("boo")).given(mock).foo();
 
 
 
  //when
 
  Result result = sistemaBajoPrueba.ejecutar();
 
 
 
  //then
 
  assertEquals(failure, result);
 
</code>
 
 
 
==Ver también==
 
* [[EasyMock]]
 
* [[Captura De Parametros]]
 
* [[Inyeccion De Mocks De Mockito Con Spring]]
 
* [http://www.dosideas.com/descargas/category/3-testing.html?download=11%3Ademo-de-mockito Proyecto de ejemplos con Mockito]
 
* [http://www.dosideas.com/java/242-mockito-o-basta-de-easymock.html Introducción a Mockito]
 
* [http://mockito.googlecode.com/svn/branches/1.8.0/javadoc/org/mockito/BDDMockito.html Javadoc de BDDMockito]
 
 
 
[[Category:TDD]]
 
[[Category:BDD]]
 
[[Category:JUnit]]
 

Revisión del 21:47 30 sep 2011

I'm relaly into it, thanks for this great stuff!