SpringBoot
Tutorial SpringBoot: Testing unitario de componentes y servicios
Desarrolla casos de testing unitario o pruebas unitarias en Spring Boot con Spring Test utilizando JUnit 5 y Mockito para crear mocks y probar servicios @Service y componentes.
Aprende SpringBoot GRATIS y certifícateConfiguración sin Spring Test con @ExtendWith(MockitoExtension.class)
En el proceso de testing unitario, es fundamental aislar el código bajo prueba de sus dependencias externas. En Spring Boot 3, es posible realizar pruebas unitarias de componentes y servicios sin cargar el contexto de Spring, utilizando Mockito como framework de mocking. Para lograr esto, se emplea la extensión de JUnit 5 @ExtendWith(MockitoExtension.class)
.
Al utilizar @ExtendWith(MockitoExtension.class)
, se integra la funcionalidad de Mockito en el ciclo de vida de JUnit 5, permitiendo la inicialización automática de los mocks. Esto agiliza las pruebas al evitar la sobrecarga de cargar todo el contexto de Spring, logrando tests más rápidos y eficientes.
A continuación, se muestra cómo configurar una clase de test para un servicio sin utilizar Spring Test:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
class MiServicioTest {
@Mock
private DependenciaExterna dependenciaExterna;
@InjectMocks
private MiServicio miServicio;
@Test
void testMetodoDelServicio() {
// Configuración de comportamiento del mock
when(dependenciaExterna.obtenerDatos()).thenReturn("datos simulados");
// Llamada al método bajo prueba
String resultado = miServicio.procesarDatos();
// Verificación del resultado
assertEquals("resultado esperado", resultado);
// Verificación de interacciones con el mock
verify(dependenciaExterna).obtenerDatos();
}
}
En el ejemplo anterior, se utilizan las anotaciones @Mock y @InjectMocks. La anotación @Mock
indica que la clase DependenciaExterna
será simulada, mientras que @InjectMocks
crea una instancia real de MiServicio
e inyecta el mock dependenciaExterna
en ella.
Es importante destacar que al no cargar el contexto de Spring, las funcionalidades como la inyección de dependencias mediante @Autowired no están disponibles. Por ello, es esencial utilizar @InjectMocks
para que Mockito realice la inyección de los mocks en los componentes que se están testeando.
Además, al emplear Mockito, se pueden definir comportamientos específicos para los mocks utilizando métodos como when
y thenReturn
, lo que permite simular diferentes escenarios y validar el correcto funcionamiento del código bajo distintas condiciones.
El uso de @ExtendWith(MockitoExtension.class)
es una práctica recomendada para pruebas unitarias que no requieren las características de Spring. Esto simplifica la configuración de los tests y mejora su rendimiento al evitar cargar componentes innecesarios.
Es conveniente recordar que las aserciones se realizan con las utilidades de JUnit 5, como assertEquals
, y que las interacciones con los mocks se pueden verificar mediante verify
, asegurando que el código funciona según lo esperado.
Configuración con Spring Test con @ExtendWith(SpringExtension.class)
En el testing unitario de aplicaciones Spring Boot 3, es común necesitar el contexto de Spring para probar componentes que dependen de la inyección de dependencias, como servicios que utilizan repositorios o componentes con anotaciones de Spring. Para facilitar este tipo de pruebas, se utiliza la extensión SpringExtension
junto con JUnit 5 y la anotación @ExtendWith(SpringExtension.class)
.
Al utilizar @ExtendWith(SpringExtension.class)
, se puede cargar el ApplicationContext de Spring en el entorno de pruebas, permitiendo el uso de características como la inyección de dependencias con @Autowired
. Esto es especialmente útil cuando se requiere probar la integración entre componentes del sistema.
A continuación, se muestra cómo configurar una clase de prueba utilizando @ExtendWith(SpringExtension.class)
:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
class MiServicioTest {
@Autowired
private MiServicio miServicio;
@Test
void testMetodoDelServicio() {
// Lógica de prueba
String resultado = miServicio.procesarDatos();
assertEquals("resultado esperado", resultado);
}
}
En este ejemplo, se utiliza la anotación @Autowired
para inyectar el bean MiServicio
directamente en la clase de prueba. El ApplicationContext se carga automáticamente, proporcionando todos los beans definidos en la configuración de la aplicación.
Es posible personalizar la carga del contexto especificando clases de configuración o ubicaciones de archivos de contexto. Por ejemplo:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {ConfiguracionDePrueba.class})
class MiServicioTest {
// ...
}
La anotación @ContextConfiguration
permite definir qué configuración se utilizará para el contexto de prueba, lo que es útil para aislar pruebas y evitar cargar toda la aplicación.
Además, si se necesita levantar únicamente una parte específica del contexto de Spring, se puede utilizar la anotación @TestConfiguration
para definir beans de prueba:
@TestConfiguration
static class ConfiguracionDePrueba {
@Bean
public RepositorioMock repositorioMock() {
return new RepositorioMock();
}
}
De esta manera, se pueden inyectar beans simulados o personalizados en el contexto de prueba, proporcionando un mayor control sobre el entorno de pruebas.
Es importante destacar que al cargar el contexto de Spring en las pruebas unitarias, los tests pueden ser más lentos debido al tiempo que toma inicializar el ApplicationContext. Por ello, se recomienda utilizar este enfoque únicamente cuando sea necesario probar la interacción entre componentes que dependen del contexto de Spring.
Para mejorar el rendimiento de las pruebas, Spring proporciona la anotación @DirtiesContext
, que indica que el contexto debe reiniciarse después de la ejecución de una prueba o clase de pruebas. Esto evita que estados compartidos afecten a otras pruebas y garantiza la consistencia en los resultados.
Ejemplo de uso de @DirtiesContext
:
@Test
@DirtiesContext
void testMetodoConCambiosEnElContexto() {
// Prueba que modifica el contexto
}
En el contexto de pruebas con Spring Boot, también es posible utilizar la anotación @SpringBootTest
para cargar el contexto completo de la aplicación. Sin embargo, para pruebas unitarias es más eficiente limitar la carga del contexto a lo mínimo necesario.
Finalmente, al combinar @ExtendWith(SpringExtension.class)
con herramientas de mocking como Mockito, se pueden crear pruebas robustas que aprovechan lo mejor de ambos mundos. Por ejemplo, se pueden inyectar mocks en el contexto de Spring utilizando la anotación @MockBean
:
@ExtendWith(SpringExtension.class)
class MiServicioTest {
@Autowired
private MiServicio miServicio;
@MockBean
private Repositorio repositorioMock;
@Test
void testConMockBean() {
when(repositorioMock.obtenerDatos()).thenReturn("datos simulados");
String resultado = miServicio.procesarDatos();
assertEquals("resultado esperado", resultado);
verify(repositorioMock).obtenerDatos();
}
}
Con @MockBean
, se reemplaza el bean real por un mock en el contexto de prueba, permitiendo controlar el comportamiento de las dependencias y realizar aserciones sobre sus interacciones.
Es fundamental entender cuándo utilizar @ExtendWith(SpringExtension.class)
en lugar de @ExtendWith(MockitoExtension.class)
. Mientras que MockitoExtension
es adecuado para pruebas unitarias puras sin contexto de Spring, SpringExtension
es necesario cuando las pruebas requieren funcionalidades proporcionadas por el framework, como la inyección de dependencias o el manejo de propiedades de entorno.
Testing de servicios con excepciones con thenThrow y assertThrows
En el desarrollo de aplicaciones con Spring Boot 3, es esencial asegurar que nuestros servicios manejan correctamente las excepciones. El testing unitario de escenarios excepcionales nos permite garantizar la robustez y fiabilidad del código.
Para simular excepciones en las dependencias de un servicio durante las pruebas, podemos utilizar el método thenThrow
de Mockito. Este método permite especificar que un mock lanzará una excepción cuando se invoque un método determinado, emulando comportamientos anómalos de las dependencias.
Por su parte, JUnit 5 proporciona el método assertThrows
para verificar que un bloque de código lanza la excepción esperada. Con assertThrows
, podemos comprobar que nuestros servicios responden adecuadamente ante situaciones excepcionales, cumpliendo con las expectativas de manejo de errores.
A continuación, veremos un ejemplo práctico de cómo probar un servicio que lanza una excepción controlada cuando ocurre un error. Supongamos un servicio CuentaService
con un método transferir(Long idOrigen, Long idDestino, BigDecimal monto)
que realiza transferencias entre cuentas.
En nuestra clase de test, utilizaremos un mock del repositorio CuentaRepository
para simular un fallo al acceder a la base de datos. Configuraremos el mock para que lance una excepción cuando se invoque el método findById
.
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.dao.DataAccessException;
@ExtendWith(MockitoExtension.class)
class CuentaServiceTest {
@Mock
private CuentaRepository cuentaRepository;
@InjectMocks
private CuentaService cuentaService;
@Test
void testTransferir_ThrowsException() {
// Configuramos el mock para lanzar una excepción
when(cuentaRepository.findById(1L)).thenThrow(new DataAccessException("Error al acceder a la base de datos") {});
// Verificamos que se lanza la excepción esperada
var exception = assertThrows(DataAccessException.class, () ->
cuentaService.transferir(1L, 2L, new BigDecimal("1000"))
);
assertEquals("Error al acceder a la base de datos", exception.getMessage());
}
}
En este test, usamos when(...).thenThrow(...)
para indicar que cuando se llame al método findById
con el argumento 1L
, el mock cuentaRepository
lanzará una DataAccessException. Esto nos permite simular un fallo en el acceso a datos sin depender de una base de datos real.
Luego, utilizamos assertThrows
para verificar que el método transferir
lanza la excepción esperada. Este método recibe la clase de la excepción que esperamos y una expresión lambda con la invocación del código bajo prueba.
Otro escenario común es cuando el servicio debe lanzar excepciones personalizadas en respuesta a ciertas condiciones de negocio. Por ejemplo, si una cuenta no tiene fondos suficientes para una transferencia, el método transferir
podría lanzar una SaldoInsuficienteException.
@Test
void testTransferir_SaldoInsuficiente() {
// Datos de prueba
var cuentaOrigen = new Cuenta(1L, "Juan", new BigDecimal("500"));
var cuentaDestino = new Cuenta(2L, "Pedro", new BigDecimal("1000"));
// Configuramos el comportamiento del mock
when(cuentaRepository.findById(1L)).thenReturn(Optional.of(cuentaOrigen));
when(cuentaRepository.findById(2L)).thenReturn(Optional.of(cuentaDestino));
// Ejecutamos y verificamos la excepción
var exception = assertThrows(SaldoInsuficienteException.class, () ->
cuentaService.transferir(1L, 2L, new BigDecimal("600"))
);
assertEquals("Saldo insuficiente en la cuenta de origen", exception.getMessage());
// Verificamos que los saldos no han cambiado
assertEquals(new BigDecimal("500"), cuentaOrigen.getSaldo());
assertEquals(new BigDecimal("1000"), cuentaDestino.getSaldo());
}
En este test, simulamos una transferencia donde el monto a transferir supera el saldo disponible en la cuenta de origen. Configuramos los mocks para que findById
devuelva objetos Cuenta con los saldos correspondientes. Al ejecutar el método transferir
, esperamos que se lance una SaldoInsuficienteException.
Utilizamos assertThrows
para capturar la excepción y realizar aserciones sobre su mensaje. Además, verificamos que los saldos de las cuentas no han cambiado, asegurando que la operación no se completó debido al error.
El uso combinado de thenThrow
y assertThrows
nos permite probar eficazmente cómo nuestros servicios manejan situaciones de error. Al simular excepciones en las dependencias y verificar que se lanzan las excepciones esperadas, podemos mejorar la calidad y fiabilidad de nuestras aplicaciones.
Probar estos escenarios de error es crucial para prevenir fallos en producción y garantizar que las excepciones se manejan y propagan adecuadamente. De este modo, aseguramos que nuestro código es resiliente y cumple con los requisitos establecidos.
Testing de servicios con argumentos usando thenAnswer y ArgumentCaptor
En las pruebas unitarias de servicios en Spring Boot 3, es habitual necesitar comprobar cómo se manejan los argumentos que se pasan a los métodos de las dependencias simuladas. Para ello, Mockito ofrece herramientas como thenAnswer
y ArgumentCaptor
, que permiten capturar y manipular los argumentos durante el testing.
Utilización de thenAnswer para comportamientos dinámicos
El método thenAnswer
proporciona la capacidad de definir respuestas personalizadas en función de los argumentos recibidos por un mock. A diferencia de thenReturn
, que devuelve un valor estático, thenAnswer
permite implementar lógica adicional en las respuestas simuladas.
Por ejemplo, consideremos un servicio ClienteService
que utiliza un repositorio ClienteRepository
para guardar información de clientes:
public class ClienteService {
private final ClienteRepository clienteRepository;
public ClienteService(ClienteRepository clienteRepository) {
this.clienteRepository = clienteRepository;
}
public Cliente registrarCliente(Cliente cliente) {
cliente.setFechaRegistro(LocalDate.now());
return clienteRepository.guardar(cliente);
}
}
Al probar el método registrarCliente
, queremos asegurarnos de que el repositorio guarda correctamente el cliente con la fecha de registro actual. Usando thenAnswer
, podemos simular el comportamiento del repositorio y verificar los datos del cliente.
@Test
void testRegistrarCliente() {
// Configuramos el mock del repositorio para devolver el cliente con un ID asignado
when(clienteRepository.guardar(any(Cliente.class))).thenAnswer(invocacion -> {
Cliente cliente = invocacion.getArgument(0);
cliente.setId(1L);
return cliente;
});
// Creamos un nuevo cliente sin ID y sin fecha de registro
var nuevoCliente = new Cliente("Ana Pérez", "ana.perez@example.com");
// Ejecutamos el método bajo prueba
Cliente clienteRegistrado = clienteService.registrarCliente(nuevoCliente);
// Verificamos que el cliente tiene un ID y una fecha de registro asignados
assertNotNull(clienteRegistrado.getId());
assertEquals(1L, clienteRegistrado.getId());
assertEquals(LocalDate.now(), clienteRegistrado.getFechaRegistro());
}
En este ejemplo, thenAnswer
nos permite acceder al argumento pasado al método guardar
y modificarlo simulando la asignación de un ID, como lo haría una base de datos real.
Capturando argumentos con ArgumentCaptor
La clase ArgumentCaptor
es una herramienta de Mockito que facilita la captura y verificación de los argumentos con los que se invocan los métodos de los mocks. Es especialmente útil cuando queremos analizar los valores pasados sin alterar el comportamiento del mock.
Continuando con el servicio ClienteService
, podríamos querer asegurarnos de que el método guardar
del repositorio se llama con un cliente que tiene la fecha de registro correcta:
@Test
void testRegistrarClienteConArgumentCaptor() {
// Creamos un captor para la clase Cliente
ArgumentCaptor<Cliente> captorCliente = ArgumentCaptor.forClass(Cliente.class);
// Creamos un nuevo cliente sin fecha de registro
var nuevoCliente = new Cliente("Luis García", "luis.garcia@example.com");
// Ejecutamos el método bajo prueba
clienteService.registrarCliente(nuevoCliente);
// Verificamos que se llamó al método guardar y capturamos el argumento
verify(clienteRepository).guardar(captorCliente.capture());
// Obtenemos el cliente capturado y verificamos sus propiedades
Cliente clienteCapturado = captorCliente.getValue();
assertEquals("Luis García", clienteCapturado.getNombre());
assertEquals("luis.garcia@example.com", clienteCapturado.getEmail());
assertEquals(LocalDate.now(), clienteCapturado.getFechaRegistro());
}
Aquí, ArgumentCaptor
nos permite extraer el cliente con el que se llamó al método guardar
y realizar aserciones sobre sus atributos sin interferir en el comportamiento del mock.
Verificación de múltiples interacciones
Cuando un servicio interactúa varias veces con un mock, podemos utilizar ArgumentCaptor
para capturar todos los argumentos de las llamadas efectuadas. Esto es útil para comprobar el orden y los valores de cada invocación.
Supongamos que nuestro servicio ClienteService
tiene un método para notificar a los clientes:
public void notificarClientes(List<Cliente> clientes) {
clientes.forEach(cliente -> emailService.enviarEmail(cliente.getEmail(), "Notificación"));
}
Para probar que se envía un email a cada cliente, capturamos los argumentos de las llamadas al método enviarEmail
:
@Test
void testNotificarClientes() {
// Creamos una lista de clientes
var clientes = List.of(
new Cliente("Carlos Ruiz", "carlos.ruiz@example.com"),
new Cliente("María López", "maria.lopez@example.com")
);
// Ejecutamos el método bajo prueba
clienteService.notificarClientes(clientes);
// Capturamos los argumentos de las llamadas al método enviarEmail
ArgumentCaptor<String> emailCaptor = ArgumentCaptor.forClass(String.class);
verify(emailService, times(2)).enviarEmail(emailCaptor.capture(), eq("Notificación"));
// Obtenemos la lista de emails capturados
var emailsEnviados = emailCaptor.getAllValues();
assertEquals(2, emailsEnviados.size());
assertTrue(emailsEnviados.contains("carlos.ruiz@example.com"));
assertTrue(emailsEnviados.contains("maria.lopez@example.com"));
}
En este caso, getAllValues()
nos devuelve una lista con todos los valores capturados, permitiendo verificar que se llamó al método con los argumentos correctos.
Comportamientos condicionados con thenAnswer
El uso de thenAnswer
nos permite definir respuestas dinámicas basadas en los argumentos o en la lógica interna. Esto es especialmente útil cuando el comportamiento del mock depende de los valores de entrada.
Consideremos un repositorio que devuelve diferentes resultados según el ID del cliente:
when(clienteRepository.buscarPorId(anyLong())).thenAnswer(invocacion -> {
Long id = invocacion.getArgument(0);
if (id == 1L) {
return Optional.of(new Cliente(1L, "Ana Pérez", "ana.perez@example.com"));
} else {
return Optional.empty();
}
});
Con este enfoque, simulamos que el repositorio devuelve un cliente existente para el ID 1L
y vacío para otros IDs, permitiendo probar cómo el servicio maneja ambos casos.
Verificación de excepciones lanzadas
También es posible utilizar thenAnswer
para lanzar excepciones personalizadas basadas en los argumentos o condiciones específicas:
when(clienteRepository.guardar(any(Cliente.class))).thenAnswer(invocacion -> {
Cliente cliente = invocacion.getArgument(0);
if (cliente.getEmail() == null) {
throw new IllegalArgumentException("El email no puede ser nulo");
}
cliente.setId(2L);
return cliente;
});
@Test
void testRegistrarClienteConEmailNulo() {
var clienteSinEmail = new Cliente("Pedro Sánchez", null);
Exception exception = assertThrows(IllegalArgumentException.class, () ->
clienteService.registrarCliente(clienteSinEmail)
);
assertEquals("El email no puede ser nulo", exception.getMessage());
}
De esta forma, validamos que el servicio responde adecuadamente ante situaciones inválidas, asegurando la integridad de los datos.
Combinación de thenAnswer y ArgumentCaptor
En situaciones complejas, podemos combinar thenAnswer
y ArgumentCaptor
para un mayor control y verificación. Por ejemplo, al probar transacciones donde es crucial validar tanto el comportamiento como los argumentos:
@Test
void testProcesarTransaccion() {
// Configuramos el repositorio para asignar un ID
when(transaccionRepository.guardar(any(Transaccion.class))).thenAnswer(invocacion -> {
Transaccion transaccion = invocacion.getArgument(0);
transaccion.setId(UUID.randomUUID());
return transaccion;
});
// Ejecutamos el método bajo prueba
var transaccion = new Transaccion("Pago", 100.0);
transaccionService.procesar(transaccion);
// Capturamos y verificamos la transacción guardada
ArgumentCaptor<Transaccion> captorTransaccion = ArgumentCaptor.forClass(Transaccion.class);
verify(transaccionRepository).guardar(captorTransaccion.capture());
Transaccion transaccionGuardada = captorTransaccion.getValue();
assertNotNull(transaccionGuardada.getId());
assertEquals("Pago", transaccionGuardada.getTipo());
assertEquals(100.0, transaccionGuardada.getMonto());
assertEquals("Procesada", transaccionGuardada.getEstado());
}
Al combinar estas herramientas, conseguimos una prueba más completa y detallada del flujo de la transacción.
Buenas prácticas en el uso de thenAnswer y ArgumentCaptor:
- Simplificar: Utilizar
thenAnswer
yArgumentCaptor
sólo cuando sea necesario. SithenReturn
es suficiente, no complicar el test. - Leerabilidad: Mantener el código de prueba limpio y fácil de entender, evitando lógica excesivamente compleja dentro de
thenAnswer
. - Aislamiento: Asegurarse de que las pruebas son independientes y no dependen de estados compartidos entre tests.
- Verificación explícita: Verificar que los métodos se llaman con los argumentos correctos y que el comportamiento del servicio es el esperado.
Aplicando estas prácticas, mejoramos la calidad y confiabilidad de nuestros tests, garantizando que los servicios funcionan correctamente en distintos escenarios y condiciones.
Ejercicios de esta lección Testing unitario de componentes y servicios
Evalúa tus conocimientos de esta lección Testing unitario de componentes y servicios con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
API Query By Example (QBE)
Identificadores y relaciones JPA
Borrar datos de base de datos
Web y Test Starters
Métodos find en repositorios
Controladores Spring MVC
Inserción de datos
CRUD Customers Spring MVC + Spring Data JPA
Backend API REST con Spring Boot
Controladores Spring REST
Uso de Spring con Thymeleaf
API Specification
Registro de usuarios
Crear entidades JPA
Asociaciones en JPA
Asociaciones de entidades JPA
Integración con Vue
Consultas JPQL
Open API y cómo agregarlo en Spring Boot
Uso de Controladores REST
Repositorios reactivos
Inyección de dependencias
Introducción a Spring Boot
CRUD y JPA Repository
Inyección de dependencias
Vista en Spring MVC con Thymeleaf
Servicios en Spring
Operadores Reactivos
Configuración de Vue
Entidades JPA
Integración con Angular
API Specification
API Query By Example (QBE)
Controladores MVC
Anotaciones y mapeo en JPA
Consultas JPQL con @Query en Spring Data JPA
Repositorios Spring Data
Inyección de dependencias
Data JPA y Mail Starters
Configuración de Angular
Controladores Spring REST
Configuración de Controladores MVC
Consultas JPQL con @Query en Spring Data JPA
Actualizar datos de base de datos
Verificar token JWT en peticiones
Login de usuarios
Integración con React
Configuración de React
Todas las lecciones de SpringBoot
Accede a todas las lecciones de SpringBoot y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Spring Boot
Introducción Y Entorno
Spring Boot Starters
Introducción Y Entorno
Inyección De Dependencias
Introducción Y Entorno
Controladores Spring Mvc
Spring Web
Vista En Spring Mvc Con Thymeleaf
Spring Web
Controladores Spring Rest
Spring Web
Open Api Y Cómo Agregarlo En Spring Boot
Spring Web
Servicios En Spring
Spring Web
Clientes Resttemplate Y Restclient
Spring Web
Rxjava En Spring Web
Spring Web
Crear Entidades Jpa
Persistencia Spring Data
Asociaciones De Entidades Jpa
Persistencia Spring Data
Repositorios Spring Data
Persistencia Spring Data
Métodos Find En Repositorios
Persistencia Spring Data
Inserción De Datos
Persistencia Spring Data
Actualizar Datos De Base De Datos
Persistencia Spring Data
Borrar Datos De Base De Datos
Persistencia Spring Data
Consultas Jpql Con @Query En Spring Data Jpa
Persistencia Spring Data
Api Query By Example (Qbe)
Persistencia Spring Data
Api Specification
Persistencia Spring Data
Repositorios Reactivos
Persistencia Spring Data
Introducción E Instalación De Apache Kafka
Mensajería Asíncrona
Crear Proyecto Con Apache Kafka
Mensajería Asíncrona
Creación De Producers
Mensajería Asíncrona
Creación De Consumers
Mensajería Asíncrona
Kafka Streams En Spring Boot
Mensajería Asíncrona
Introducción A Spring Webflux
Reactividad Webflux
Spring Data R2dbc
Reactividad Webflux
Controlador Rest Reactivo Basado En Anotaciones
Reactividad Webflux
Controlador Rest Reactivo Funcional
Reactividad Webflux
Operadores Reactivos Básicos
Reactividad Webflux
Operadores Reactivos Avanzados
Reactividad Webflux
Cliente Reactivo Webclient
Reactividad Webflux
Introducción A Spring Security
Seguridad Con Spring Security
Seguridad Basada En Formulario En Mvc Con Thymeleaf
Seguridad Con Spring Security
Registro De Usuarios
Seguridad Con Spring Security
Login De Usuarios
Seguridad Con Spring Security
Verificar Token Jwt En Peticiones
Seguridad Con Spring Security
Seguridad Jwt En Api Rest Spring Web
Seguridad Con Spring Security
Seguridad Jwt En Api Rest Reactiva Spring Webflux
Seguridad Con Spring Security
Autenticación Y Autorización Con Anotaciones
Seguridad Con Spring Security
Testing Unitario De Componentes Y Servicios
Testing Con Spring Test
Testing De Repositorios Spring Data Jpa
Testing Con Spring Test
Testing Controladores Spring Mvc Con Thymeleaf
Testing Con Spring Test
Testing Controladores Rest Con Json
Testing Con Spring Test
Testing De Aplicaciones Reactivas Webflux
Testing Con Spring Test
Testing De Seguridad Spring Security
Testing Con Spring Test
Testing Con Apache Kafka
Testing Con Spring Test
Integración Con Angular
Integración Frontend
Integración Con React
Integración Frontend
Integración Con Vue
Integración Frontend
En esta lección
Objetivos de aprendizaje de esta lección
- Aprender a ejecutar pruebas unitarias en Spring Boot
- Conocer las anotaciones para configurar tests
- Aprender a usar Mocks en Spring