Pruebas en Java: unit, integration, e2e — guía completa

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Pruebas en Java: desde pruebas unitarias hasta pruebas de extremo a extremo



La calidad del código es uno de los principales indicadores del profesionalismo de un desarrollador. En el mundo de Java, las pruebas se han convertido no solo en una buena práctica, sino en un estándar de la industria. Sin pruebas confiables, es difícil mantener proyectos grandes, implementar nuevas funciones y refactorizar el código con confianza. En este artículo, analizaremos tres niveles clave de pruebas: unit (pruebas unitarias), integration (pruebas de integración) y e2e (pruebas de extremo a extremo). Aprenderás en qué se diferencian, cómo escribirlas correctamente en Java y qué herramientas usar.



La pirámide de pruebas y por qué es importante

Antes de profundizar en los detalles, vale la pena recordar el concepto de la pirámide de pruebas (Mike Cohn). Visualiza la proporción ideal de pruebas en diferentes niveles:

  • Pruebas unitarias (base de la pirámide) — las más rápidas, económicas y numerosas. Deberían ser alrededor del 70%.
  • Pruebas de integración (centro) — verifican la interacción entre componentes. Alrededor del 20%.
  • Pruebas E2E (cúspide) — las más lentas y costosas, pero críticamente importantes para verificar escenarios de usuario. Alrededor del 10%.

Mantener esta proporción permite obtener la máxima confianza en el código con el mínimo tiempo de ejecución de las pruebas.



1. Pruebas unitarias en Java

Las pruebas unitarias verifican de forma aislada una «unidad» de código — generalmente un método o una clase. Su objetivo principal es asegurarse de que la lógica del método funcione correctamente, independientemente de las dependencias externas (base de datos, API, sistema de archivos). Para el aislamiento se utilizan objetos mock.



Herramientas principales

  • JUnit 5 — el framework estándar para escribir pruebas.
  • Mockito — biblioteca para crear objetos mock y verificar interacciones.
  • AssertJ — biblioteca para aserciones fluidas (mejora la legibilidad).


Ejemplo de prueba unitaria con JUnit 5 y Mockito

Supongamos que tenemos un servicio UserService que depende de UserRepository:

public class UserService {    private final UserRepository repository;        public UserService(UserRepository repository) {        this.repository = repository;    }        public User findById(Long id) {        return repository.findById(id)                .orElseThrow(() -> new UserNotFoundException("User not found"));    }}

Prueba para este método:

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;import java.util.Optional;import static org.junit.jupiter.api.Assertions.*;import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)class UserServiceTest {

@Mock private UserRepository repository;

@InjectMocks private UserService userService;

@Test void testFindById_UserExists() { // Given Long userId = 1L; User expectedUser = new User(userId, "Alice"); when(repository.findById(userId)).thenReturn(Optional.of(expectedUser));

// When User actualUser = userService.findById(userId);

// Then assertNotNull(actualUser); assertEquals("Alice", actualUser.getName()); verify(repository).findById(userId); }

@Test void testFindById_UserNotFound() { // Given Long userId = 99L; when(repository.findById(userId)).thenReturn(Optional.empty());

// When & Then assertThrows(UserNotFoundException.class, () -> userService.findById(userId)); }}

Best practices:

  • Pruebe una so

Blogs

Book Recommendations