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
- Mocks: Objetos simulados que imitan el comportamiento de objetos reales en un entorno controlado.
- 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:
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
-
Crear el Mock:
UserRepository mockRepository = Mockito.mock(UserRepository.class);- Creamos un mock de
UserRepositoryusando Mockito.
- Creamos un mock de
-
Inyectar el Mock:
UserService userService = new UserService(mockRepository);- Inyectamos el mock en una instancia de
UserService.
- Inyectamos el mock en una instancia de
-
Llamar al Método:
userService.addUser("John Doe");- Llamamos al método
addUserdeUserService.
- Llamamos al método
-
Verificar la Interacción:
verify(mockRepository).save("John Doe");- Verificamos que el método
savedeUserRepositoryse llamó con el argumento "John Doe".
- Verificamos que el método
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:
Verificar que Nunca se Llamó
Podemos verificar que un método nunca se llamó:
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.
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
