Vamos a empezar desde lo más básico. ¿Por qué necesitamos testing? Seguro que no quieres que tus usuarios se topen con bugs en producción, ¿verdad? El testing permite detectar y corregir problemas antes de que dañen tu aplicación o tu reputación. Y Spring Boot ofrece herramientas cómodas para facilitar esa tarea.
Spring Boot se integra con librerías populares de testing como JUnit y TestNG, y aporta funcionalidades adicionales a través de spring-boot-starter-test. Este starter incluye todo lo necesario para escribir tests:
- JUnit 5 para escribir pruebas.
- AssertJ para comprobaciones concisas.
- Hamcrest para expresiones potentes y legibles.
- Mockito para crear stubs y mocks.
- Spring Test — un módulo de Spring pensado para ayudarnos a testear aplicaciones en el contexto de Spring.
Configuración del entorno de testing
Para empezar, asegúrate de que en tu pom.xml o build.gradle tienes la dependencia spring-boot-starter-test.
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Fundamentos de Spring Boot Test
Con spring-boot-starter-test obtenemos un mecanismo potente para testear componentes de aplicaciones Spring: controladores, servicios, repositorios e incluso todo el sistema.
Anotaciones de Spring Boot Test
@SpringBootTest— arranca todo el contexto de la aplicación para ejecutar tests de integración.@MockBean— crea versiones mock de los beans. Útil para aislar la lógica que estás testeando.@WebMvcTest— levanta solo el contexto de Spring MVC, ideal para testear controllers REST.@DataJpaTest— crea un contexto para testear repositorios y trabajar con JPA.
Ejemplo: imagina que tenemos un método en un servicio que devuelve una lista de usuarios. Usando las anotaciones podemos testear su lógica.
// UserService.java
@Service
public class UserService {
public List<String> getUsers() {
return Arrays.asList("Alice", "Bob", "Charlie");
}
}
// UserServiceTest.java
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testGetUsers() {
List<String> users = userService.getUsers();
assertEquals(3, users.size());
assertTrue(users.contains("Alice"));
}
}
Práctica de testing
Ahora veamos cómo testear distintas partes de nuestra aplicación.
Testing de controllers REST
Controller típico:
// UserController.java
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping
public List<String> getUsers() {
return List.of("Alice", "Bob", "Charlie");
}
}
Testeando con @WebMvcTest:
@WebMvcTest(UserController.class)
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testGetUsers() throws Exception {
mockMvc.perform(get("/users"))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0]").value("Alice"))
.andExpect(jsonPath("$[1]").value("Bob"));
}
}
¿Qué pasa aquí?
- Usamos
MockMvcpara ejecutar peticiones HTTP contra nuestro controller. - El método
perform()envía un GET a/users. - Con
andExpect()comprobamos el status de la respuesta y el contenido del array JSON.
Testing de repositorios
Veamos un ejemplo usando JPA. Escribimos un repositorio para gestionar la entidad User.
Entidad:
// User.java
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
// getters & setters
}
Repositorio:
// UserRepository.java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByName(String name);
}
Test del repositorio:
@DataJpaTest
public class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
public void testFindByName() {
// Arrange
User user = new User();
user.setName("Alice");
userRepository.save(user);
// Act
List<User> users = userRepository.findByName("Alice");
// Assert
assertEquals(1, users.size());
assertEquals("Alice", users.get(0).getName());
}
}
Aclaraciones:
- Usamos la anotación
@DataJpaTestpara configurar automáticamente una base de datos embebida (por ejemplo, H2 Database). - En la fase Arrange añadimos datos de prueba al repositorio.
- En la fase Act ejecutamos el método que queremos testear.
- En la fase Assert comprobamos los resultados.
Testing de integración
A veces necesitamos testear la aplicación completa, incluyendo todos los niveles —desde controllers hasta la base de datos. Para eso usamos @SpringBootTest.
Ejemplo:
@SpringBootTest
public class IntegrationTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testGetUsers() throws Exception {
mockMvc.perform(get("/users"))
.andExpect(status().isOk())
.andExpect(content().string("[\"Alice\",\"Bob\",\"Charlie\"]"));
}
}
Puntos importantes
1. Usar H2 para testing.
Spring Boot conecta automáticamente con H2 Database en los tests si usas JPA. Esto permite testear la base de datos sin levantar un servidor real.
2. Usar mock-objetos con Mockito.
Mockito permite mockear dependencias para aislar el código que estás testeando. Por ejemplo:
@MockBean
private UserService userService;
@Test
public void testMockedService() {
when(userService.getUsers()).thenReturn(List.of("MockedUser"));
// Your test code here
}
Ventajas de testear con Spring Boot
- Integración cómoda. Todas las herramientas están integradas, no necesitas configurar nada a mano.
- Eficiencia. Los tests se ejecutan rápido, incluso usando la base de datos embebida.
- Fiabilidad. Tener buena cobertura de tests ayuda a evitar sorpresas en producción.
Ahora ya tienes las nociones básicas necesarias para testear aplicaciones con Spring Boot. Recuerda, cualquier cambio en el código merece una comprobación mediante tests. Testea todo lo que se mueve (y hasta lo que aún no se mueve). Y, como se dice, "mejor una prueba pequeña que una gran disculpa ante el cliente".
GO TO FULL VERSION