En este tema, aprenderemos cómo integrar Mockito con JUnit para crear pruebas unitarias más efectivas y robustas. Mockito es una biblioteca de Java que permite crear objetos simulados (mocks) para pruebas unitarias. Esto es especialmente útil cuando queremos aislar el código que estamos probando de sus dependencias.
Contenido
- ¿Qué es Mockito?
 - Configuración de Mockito con JUnit
 - Creando Mocks con Mockito
 - Inyectando Mocks en el Código
 - Verificando Interacciones
 - Ejemplo Práctico
 - Ejercicios Prácticos
 
- ¿Qué es Mockito?
 
Mockito es una biblioteca de Java que permite crear objetos simulados (mocks) para pruebas unitarias. Los mocks son objetos que imitan el comportamiento de objetos reales en un entorno controlado. Esto es útil para probar el comportamiento de una clase sin depender de sus dependencias externas.
- Configuración de Mockito con JUnit
 
Para usar Mockito con JUnit, primero necesitamos agregar las dependencias necesarias a nuestro proyecto. Si estás usando Maven, agrega las siguientes dependencias a tu archivo pom.xml:
<dependencies>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>3.11.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.7.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>Si estás usando Gradle, agrega las siguientes líneas a tu archivo build.gradle:
dependencies {
    testImplementation 'org.mockito:mockito-core:3.11.2'
    testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.7.2'
}
- Creando Mocks con Mockito
 
Para crear un mock con Mockito, usamos el método Mockito.mock(). Aquí hay un ejemplo básico:
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class MyServiceTest {
    @Test
    public void testMyService() {
        // Crear un mock de la clase Dependency
        Dependency dependencyMock = Mockito.mock(Dependency.class);
        // Definir el comportamiento del mock
        Mockito.when(dependencyMock.someMethod()).thenReturn("Mocked Response");
        // Usar el mock en la clase que estamos probando
        MyService myService = new MyService(dependencyMock);
        String result = myService.performAction();
        // Verificar el resultado
        assertEquals("Mocked Response", result);
    }
}
- Inyectando Mocks en el Código
 
En lugar de crear manualmente los mocks, podemos usar anotaciones para simplificar el proceso. Mockito proporciona la anotación @Mock para crear mocks y @InjectMocks para inyectarlos en la clase que estamos probando.
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
public class MyServiceTest {
    @Mock
    private Dependency dependencyMock;
    @InjectMocks
    private MyService myService;
    @BeforeEach
    public void setUp() {
        MockitoAnnotations.openMocks(this);
    }
    @Test
    public void testMyService() {
        // Definir el comportamiento del mock
        when(dependencyMock.someMethod()).thenReturn("Mocked Response");
        // Usar el mock en la clase que estamos probando
        String result = myService.performAction();
        // Verificar el resultado
        assertEquals("Mocked Response", result);
    }
}
- Verificando Interacciones
 
Además de definir el comportamiento de los mocks, también podemos verificar que ciertos métodos fueron llamados con los argumentos correctos. Esto se hace usando el método Mockito.verify().
import static org.mockito.Mockito.verify;
@Test
public void testMyService() {
    // Definir el comportamiento del mock
    when(dependencyMock.someMethod()).thenReturn("Mocked Response");
    // Usar el mock en la clase que estamos probando
    String result = myService.performAction();
    // Verificar el resultado
    assertEquals("Mocked Response", result);
    // Verificar que el método someMethod() fue llamado una vez
    verify(dependencyMock).someMethod();
}
- Ejemplo Práctico
 
Vamos a ver un ejemplo más completo que incluye la creación de mocks, la inyección de dependencias y la verificación de interacciones.
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class UserServiceTest {
    @Mock
    private UserRepository userRepositoryMock;
    @InjectMocks
    private UserService userService;
    @BeforeEach
    public void setUp() {
        MockitoAnnotations.openMocks(this);
    }
    @Test
    public void testGetUser() {
        // Definir el comportamiento del mock
        User mockUser = new User("John", "Doe");
        when(userRepositoryMock.findUserById(1)).thenReturn(mockUser);
        // Usar el mock en la clase que estamos probando
        User result = userService.getUser(1);
        // Verificar el resultado
        assertEquals("John", result.getFirstName());
        assertEquals("Doe", result.getLastName());
        // Verificar que el método findUserById() fue llamado una vez con el argumento 1
        verify(userRepositoryMock).findUserById(1);
    }
}
- Ejercicios Prácticos
 
Ejercicio 1: Crear y Usar Mocks
- Crea una clase 
Calculatorcon un métodoadd(int a, int b)que devuelve la suma deayb. - Crea una clase 
CalculatorServiceque tenga una dependencia deCalculator. - Escribe una prueba unitaria para 
CalculatorServiceusando Mockito para simular el comportamiento deCalculator. 
Ejercicio 2: Verificar Interacciones
- Modifica la clase 
CalculatorServicepara que tenga un métodocalculateSum(int a, int b)que use el métodoadddeCalculator. - Escribe una prueba unitaria para 
calculateSumque verifique que el métodoadddeCalculatorfue llamado con los argumentos correctos. 
Soluciones
Solución Ejercicio 1
// Calculator.java
public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
}
// CalculatorService.java
public class CalculatorService {
    private Calculator calculator;
    public CalculatorService(Calculator calculator) {
        this.calculator = calculator;
    }
    public int calculateSum(int a, int b) {
        return calculator.add(a, b);
    }
}
// CalculatorServiceTest.java
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
public class CalculatorServiceTest {
    @Mock
    private Calculator calculatorMock;
    @InjectMocks
    private CalculatorService calculatorService;
    @BeforeEach
    public void setUp() {
        MockitoAnnotations.openMocks(this);
    }
    @Test
    public void testCalculateSum() {
        // Definir el comportamiento del mock
        when(calculatorMock.add(2, 3)).thenReturn(5);
        // Usar el mock en la clase que estamos probando
        int result = calculatorService.calculateSum(2, 3);
        // Verificar el resultado
        assertEquals(5, result);
    }
}Solución Ejercicio 2
import static org.mockito.Mockito.verify;
@Test
public void testCalculateSum() {
    // Definir el comportamiento del mock
    when(calculatorMock.add(2, 3)).thenReturn(5);
    // Usar el mock en la clase que estamos probando
    int result = calculatorService.calculateSum(2, 3);
    // Verificar el resultado
    assertEquals(5, result);
    // Verificar que el método add() fue llamado una vez con los argumentos 2 y 3
    verify(calculatorMock).add(2, 3);
}Conclusión
En este tema, hemos aprendido cómo usar Mockito con JUnit para crear pruebas unitarias más efectivas. Hemos cubierto cómo configurar Mockito, crear mocks, inyectar mocks en el código, y verificar interacciones. Además, hemos visto un ejemplo práctico y proporcionado ejercicios para reforzar los conceptos aprendidos. Con estas herramientas, estarás mejor preparado para escribir pruebas unitarias robustas y mantener un código de alta calidad.
Curso de JUnit
Módulo 1: Introducción a JUnit
Módulo 2: Anotaciones Básicas de JUnit
- Entendiendo @Test
 - Usando @Before y @After
 - Usando @BeforeClass y @AfterClass
 - Ignorando Tests con @Ignore
 
Módulo 3: Aserciones en JUnit
Módulo 4: Tests Parametrizados
- Introducción a los Tests Parametrizados
 - Creando Tests Parametrizados
 - Usando @ParameterizedTest
 - Tests Parametrizados Personalizados
 
Módulo 5: Suites de Tests
Módulo 6: Mocking con JUnit
Módulo 7: Características Avanzadas de JUnit
Módulo 8: Mejores Prácticas y Consejos
- Escribiendo Tests Efectivos
 - Organizando el Código de Tests
 - Desarrollo Guiado por Tests (TDD)
 - Integración Continua con JUnit
 
