En este tema, aprenderemos cómo verificar interacciones con objetos mock en JUnit utilizando Mockito. Verificar interacciones es crucial para asegurarse de que los métodos de los mocks se llamen con los argumentos correctos y en el orden esperado. Esto es especialmente útil en pruebas unitarias donde queremos asegurarnos de que nuestro código interactúa correctamente con sus dependencias.

Conceptos Clave

  1. Mocks: Objetos simulados que imitan el comportamiento de objetos reales en un entorno controlado.
  2. Verificación de Interacciones: Proceso de comprobar que los métodos de los mocks se llamaron con los argumentos correctos y en el orden esperado.

Configuración Inicial

Antes de comenzar, asegúrate de tener las siguientes dependencias en tu archivo pom.xml si estás usando Maven:

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

Ejemplo Práctico

Vamos a crear un ejemplo práctico para ilustrar cómo verificar interacciones con Mockito.

Paso 1: Crear las Clases a Probar

Supongamos que tenemos una clase UserService que depende de una clase UserRepository.

public class UserService {
    private UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void addUser(String user) {
        userRepository.save(user);
    }
}

Y la interfaz UserRepository:

public interface UserRepository {
    void save(String user);
}

Paso 2: Crear el Test

Ahora, vamos a crear un test para UserService donde verificaremos que el método save de UserRepository se llama correctamente.

import static org.mockito.Mockito.*;

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

public class UserServiceTest {

    @Test
    public void testAddUser() {
        // Crear el mock de UserRepository
        UserRepository mockRepository = Mockito.mock(UserRepository.class);

        // Crear una instancia de UserService con el mock
        UserService userService = new UserService(mockRepository);

        // Llamar al método addUser
        userService.addUser("John Doe");

        // Verificar que el método save se llamó con el argumento "John Doe"
        verify(mockRepository).save("John Doe");
    }
}

Explicación del Código

  1. Crear el Mock: UserRepository mockRepository = Mockito.mock(UserRepository.class);

    • Creamos un mock de UserRepository usando Mockito.
  2. Inyectar el Mock: UserService userService = new UserService(mockRepository);

    • Inyectamos el mock en una instancia de UserService.
  3. Llamar al Método: userService.addUser("John Doe");

    • Llamamos al método addUser de UserService.
  4. Verificar la Interacción: verify(mockRepository).save("John Doe");

    • Verificamos que el método save de UserRepository se llamó con el argumento "John Doe".

Verificaciones Adicionales

Mockito ofrece varias formas de verificar interacciones adicionales:

Verificar Número de Llamadas

Podemos verificar cuántas veces se llamó un método:

verify(mockRepository, times(1)).save("John Doe");

Verificar que Nunca se Llamó

Podemos verificar que un método nunca se llamó:

verify(mockRepository, never()).delete(anyString());

Verificar Orden de Llamadas

Podemos verificar el orden en que se llamaron los métodos:

InOrder inOrder = inOrder(mockRepository);
inOrder.verify(mockRepository).save("John Doe");
inOrder.verify(mockRepository).notifyUser("John Doe");

Ejercicio Práctico

Ejercicio

Crea una clase OrderService que dependa de una interfaz OrderRepository. Implementa un método placeOrder en OrderService que llame a saveOrder en OrderRepository. Escribe un test para verificar que saveOrder se llama correctamente.

Solución

Clases a Probar

public class OrderService {
    private OrderRepository orderRepository;

    public OrderService(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }

    public void placeOrder(String order) {
        orderRepository.saveOrder(order);
    }
}

public interface OrderRepository {
    void saveOrder(String order);
}

Test

import static org.mockito.Mockito.*;

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

public class OrderServiceTest {

    @Test
    public void testPlaceOrder() {
        // Crear el mock de OrderRepository
        OrderRepository mockRepository = Mockito.mock(OrderRepository.class);

        // Crear una instancia de OrderService con el mock
        OrderService orderService = new OrderService(mockRepository);

        // Llamar al método placeOrder
        orderService.placeOrder("Order123");

        // Verificar que el método saveOrder se llamó con el argumento "Order123"
        verify(mockRepository).saveOrder("Order123");
    }
}

Conclusión

En esta sección, hemos aprendido cómo verificar interacciones con objetos mock en JUnit utilizando Mockito. La verificación de interacciones es una herramienta poderosa para asegurarse de que nuestro código interactúa correctamente con sus dependencias. Hemos cubierto los conceptos básicos y algunos ejemplos prácticos, así como ejercicios para reforzar el aprendizaje. En el siguiente módulo, exploraremos características avanzadas de JUnit.

© Copyright 2024. Todos los derechos reservados