Testing
En desarrollo profesional es muy importante probar el código automáticamente.
Esto se hace mediante tests.
Los tests permiten:
- detectar errores
- asegurar que el código funciona
- evitar que cambios rompan el sistema
- mejorar la calidad del software
Spring Boot incluye soporte para testing usando herramientas como:
- JUnit
- Mockito
- Spring Test
1. Tipos de tests #
En una aplicación Spring Boot existen varios tipos de pruebas.
| tipo | objetivo |
|---|---|
| Test unitario | probar una clase aislada |
| Test de servicio | probar lógica de negocio |
| Test de repositorio | probar acceso a base de datos |
| Test de controller | probar endpoints |
| Test de integración | probar varias capas juntas |
2. Dependencia de testing #
Spring Boot incluye testing por defecto.
En pom.xml aparece:
1<dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-test</artifactId> 4 <scope>test</scope> 5</dependency>
Esto incluye:
- JUnit
- Mockito
- Spring Test
3. Estructura de tests #
Los tests están en:
1src/test/java
Ejemplo:
1src/test/java/com/example/app 2 3UserServiceTest.java 4UserControllerTest.java
4. Test unitario simple #
Ejemplo de test básico con JUnit.
Clase a probar:
1public class CalculatorService { 2 3 public int sum(int a, int b) { 4 return a + b; 5 } 6 7}
5. Test #
1import org.junit.jupiter.api.Test; 2import static org.junit.jupiter.api.Assertions.*; 3 4class CalculatorServiceTest { 5 6 @Test 7 void sumShouldReturnCorrectResult() { 8 9 CalculatorService service = new CalculatorService(); 10 11 int result = service.sum(2, 3); 12 13 assertEquals(5, result); 14 15 } 16 17}
6. Explicación #
| método | función |
|---|---|
@Test | indica un test |
assertEquals | verifica resultado |
7. Testing de servicios con Mockito #
Muchas veces el servicio depende de un repository.
Ejemplo:
1@Service 2public class UserService { 3 4 private final UserRepository repository; 5 6 public UserService(UserRepository repository) { 7 this.repository = repository; 8 } 9 10 public List<User> getUsers() { 11 return repository.findAll(); 12 } 13 14}
8. Problema #
No queremos usar una base de datos real en el test.
Por eso usamos Mockito.
Mockito crea objetos simulados (mocks).
9. Test con Mockito #
1import org.junit.jupiter.api.Test; 2import static org.mockito.Mockito.*; 3import static org.junit.jupiter.api.Assertions.*; 4 5class UserServiceTest { 6 7 @Test 8 void shouldReturnUsers() { 9 10 UserRepository repository = mock(UserRepository.class); 11 12 when(repository.findAll()) 13 .thenReturn(List.of(new User("Ana"))); 14 15 UserService service = new UserService(repository); 16 17 List<User> users = service.getUsers(); 18 19 assertEquals(1, users.size()); 20 21 } 22 23}
10. Explicación #
| método | función |
|---|---|
| mock() | crea objeto falso |
| when() | define comportamiento |
| thenReturn() | define resultado |
11. Testing de Controllers #
Para probar controllers usamos MockMvc.
Esto permite simular peticiones HTTP.
12. Ejemplo controller #
1@RestController 2@RequestMapping("/hello") 3public class HelloController { 4 5 @GetMapping 6 public String hello() { 7 return "Hola mundo"; 8 } 9 10}
13. Test #
1@SpringBootTest 2@AutoConfigureMockMvc 3class HelloControllerTest { 4 5 @Autowired 6 private MockMvc mockMvc; 7 8 @Test 9 void shouldReturnHello() throws Exception { 10 11 mockMvc.perform(get("/hello")) 12 .andExpect(status().isOk()) 13 .andExpect(content().string("Hola mundo")); 14 15 } 16 17}
14. Explicación #
| método | función |
|---|---|
MockMvc | simula peticiones HTTP |
perform() | ejecuta petición |
andExpect() | verifica respuesta |
15. Testing de repositorios #
Para probar repositorios usamos:
1@DataJpaTest
Esto inicia solo la capa de base de datos.
16. Ejemplo #
1@DataJpaTest 2class UserRepositoryTest { 3 4 @Autowired 5 private UserRepository repository; 6 7 @Test 8 void shouldSaveUser() { 9 10 User user = new User(); 11 user.setName("Ana"); 12 13 User saved = repository.save(user); 14 15 assertNotNull(saved.getId()); 16 17 } 18 19}
17. Testing de integración #
Un test de integración prueba varias capas juntas.
Ejemplo:
1Controller + Service + Repository
18. Ejemplo #
1@SpringBootTest 2class UserIntegrationTest { 3 4 @Autowired 5 private UserService service; 6 7 @Test 8 void shouldCreateUser() { 9 10 User user = new User(); 11 user.setName("Ana"); 12 13 User saved = service.createUser(user); 14 15 assertNotNull(saved.getId()); 16 17 } 18 19}
19. Buenas prácticas en testing #
Testear lógica de negocio #
La lógica en services debe tener tests.
No usar base de datos real en tests unitarios #
Usar Mockito.
Nombres claros en tests #
Ejemplo:
1shouldCreateUser 2shouldReturnUsers 3shouldThrowException
Un test -> un comportamiento #
Cada test debe comprobar una sola cosa.
20. Estructura típica de tests #
1src/test/java 2 3controller 4service 5repository 6integration
Resumen del tema
Conceptos clave #
- Pirámide de Testing en Spring Boot (
spring-boot-starter-test): JUnit 5 Jupiter, Mockito y AssertJ/Hamcrest preconfigurados. - Pruebas Unitarias Aisladas con Mockito: uso de
mock(),@Mock,@InjectMocks,when().thenReturn()yverify()para aislar la lógica del servicio sin levantar el contexto de Spring. - Pruebas de Controladores con
@WebMvcTestyMockMvc: pruebas rápidas del slice web simulando peticiones HTTP (perform(get(...))), verificando códigos de estado (status().isOk()) y payloads JSON (jsonPath("$[0].name")). - Pruebas de Repositorios con
@DataJpaTest: configuración de BD embebida en memoria (H2/Testcontainers) y rollback automático de transacciones. - Pruebas de Integración con
@SpringBootTest: carga completa delApplicationContextpara verificar la interacción end-to-end de todas las capas.
Qué debes recordar #
Usa pruebas unitarias con Mockito para servicios, @WebMvcTest con MockMvc para controladores y reserva @SpringBootTest para integración global.