Mockito es un framework de código abierto para crear pruebas unitarias en Java publicado bajo la licencia MIT[3][4]​ El framework permite la creación de objetos dobles de prueba (objetos simulados) en pruebas de unidad automatizada para el desarrollo guiado por pruebas (TDD) o desarrollo dirigido por el comportamiento (BDD).

Mockito
Información general
Tipo de programa framework
Desarrollador Szczepan Faber, Brice Dutheil, Rafael Winterhalter, Tim van der Lippe and others.
Licencia MIT License[1]
Información técnica
Programado en Java
Versiones
Última versión estable 4.3.1 ( 25 de enero de 2022 (2 años, 11 meses y 4 días)[2]​)
Enlaces

El nombre y el logotipo del marco son un juego de palabras con los mojitos, un tipo de bebida.

Características

editar

Mockito permite a los desarrolladores verificar el comportamiento del sistema bajo prueba (SUT) sin establecer expectativas de antemano.[5]​ Una de las críticas a los objetos mock es que hay un estrecho acoplamiento del código de prueba con el sistema bajo prueba.[6]​ Mockito intenta eliminar el patrón esperar-ejecutar-verificar eliminando la especificación de expectativas.[7]​ Mockito también proporciona algunas anotaciones para reducir el código repetitivo.[8]

Orígenes

editar

Mockito Empezó por expandir en la sintaxis y funcionalidad de EasyMock.[9][10]

Ejemplo

editar

Consideremos este programa desacoplado de Hola Mundo; podemos probar unitariamente algunas de sus partes, utilizando objetos simulados para otras partes.

package org.examples;

import java.io.IOException;

public class HelloApplication {

   public static interface Greeter {
      String getGreeting(String subject);
      String getIntroduction(String actor);
   }
   
   public static class HelloGreeter implements Greeter {
      private String hello;
      private String segmenter;
      
      public HelloGreeter(String hello, String segmenter) {
         this.hello = hello;
         this.segmenter = segmenter;
      }
      public String getGreeting(String subject) {
         return hello + " " + subject; 
      }
      public String getIntroduction(String actor) {
         return actor+segmenter;
      }
   }
   
   public static interface HelloActable {
      void sayHello(String actor, String subject) throws IOException;
   }
   
   public static class HelloAction implements HelloActable {
      private Greeter helloGreeter;
      private Appendable helloWriter;

      public HelloAction(Greeter helloGreeter, Appendable helloWriter) {
         super();
         this.helloGreeter = helloGreeter;
         this.helloWriter = helloWriter;
      }
      public void sayHello(String actor, String subject) throws IOException { 
         helloWriter.append(helloGreeter.getIntroduction(actor)).append(helloGreeter.getGreeting(subject));
      }
   }

   public static void main(String... args) throws IOException {
      new HelloAction(new HelloGreeter("hello", ": "), System.out).sayHello("application", "world");
   }

}
application: hello world

El resultado del lanzamiento de HelloApplication será el siguiente:

package org.examples;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.Before;
import org.junit.Test;

import org.examples.HelloApplication.HelloActable;
import org.examples.HelloApplication.HelloAction;
import org.examples.HelloApplication.Greeter;

public class HelloActionUnitTest {
   
   Greeter helloGreeterMock;
   Appendable helloWriterMock;
   HelloActable helloAction;
   
   @Before
   public void setUp() {
      helloGreeterMock = mock(Greeter.class);
      helloWriterMock = mock(Appendable.class);
      helloAction = new HelloAction(helloGreeterMock, helloWriterMock);
   }
   
   @Test
   public void testSayHello() throws Exception {
      when(helloWriterMock.append(any(String.class))).thenReturn(helloWriterMock);
      when(helloGreeterMock.getIntroduction(eq("unitTest"))).thenReturn("unitTest : ");
      when(helloGreeterMock.getGreeting(eq("world"))).thenReturn("hi world");
      
      helloAction.sayHello("unitTest", "world");
      
      verify(helloGreeterMock).getIntroduction(eq("unitTest"));
      verify(helloGreeterMock).getGreeting(eq("world"));

      verify(helloWriterMock, times(2)).append(any(String.class));
      verify(helloWriterMock, times(1)).append(eq("unitTest : "));
      verify(helloWriterMock, times(1)).append(eq("hi world"));
   }
}

unitTest : hi world

package org.examples;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.Before;
import org.junit.Test;

import org.examples.HelloApplication.HelloActable;
import org.examples.HelloApplication.HelloAction;
import org.examples.HelloApplication.Greeter;
import org.examples.HelloApplication.HelloGreeter;

public class HelloActionIntegrationTest {
   HelloActable helloAction;
   Greeter helloGreeter;
   Appendable helloWriterMock;
   
   @Before
   public void setUp() {
      helloGreeter = new HelloGreeter("welcome", " says ");
      helloWriterMock = mock(Appendable.class);
      helloAction = new HelloAction(helloGreeter, helloWriterMock);
   }
   
   @Test
   public void testSayHello() throws Exception {
      when(helloWriterMock.append(any(String.class))).thenReturn(helloWriterMock);

      helloAction.sayHello("integrationTest", "universe");

      verify(helloWriterMock, times(2)).append(any(String.class));
      verify(helloWriterMock, times(1)).append(eq("integrationTest says "));
      verify(helloWriterMock, times(1)).append(eq("welcome universe"));
   }
}

Utiliza objetos simulados sólo en lugar de las interfaces de Appendable, utiliza las implementaciones reales para otras interfaces (HelloActable y Greeter), y asume implícitamente el siguiente caso de uso:

integrationTest says welcome universe

Como se puede ver en las declaraciones de importación de las clases HelloActionUnitTest y HelloActionIntegrationTest, es necesario poner algunos jars de Mockito y JUnit en su ruta de clases para poder compilar y ejecutar las clases de prueba.

Véase también

editar

Referencias

editar
  1. «License · mockito/mockito Wiki · GitHub». Consultado el 30 de agosto de 2019. 
  2. «Maven Repository · org.mockito/mockito-core · Maven Central Repository Search». Consultado el 19 de febrero de 2022. 
  3. «Mockito in six easy examples». 2009. Consultado el 5 de octubre de 2012. 
  4. «What's the best mock framework for Java?». Consultado el 29 de diciembre de 2010. 
  5. «Features and Motivations». Consultado el 29 de diciembre de 2010. 
  6. Fowler, Martin (2007). «Mocks Aren't Stubs». Consultado el 29 de diciembre de 2010. 
  7. Faber, Szczepan. «Death Wish». Archivado desde el original el 30 de noviembre de 2009. Consultado el 29 de diciembre de 2010. 
  8. Kaczanowski, Tomek. «Mockito - Open Source Java Mocking Framework». Consultado el 17 de septiembre de 2013. 
  9. Faber, Szczepan. «Mockito». Archivado desde el original el 17 de agosto de 2018. Consultado el 29 de diciembre de 2010. 
  10. «Mockito Home Page». Consultado el 29 de diciembre de 2010.