Qué es una prueba unitaria
Una prueba unitaria verifica el comportamiento de una unidad de código, normalmente una función o una clase, en aislamiento. La idea es darle una entrada conocida, ejecutar la unidad y comparar el resultado con lo esperado.
function sumar(a, b) {
return a + b;
}
test('suma dos números', () => {
expect(sumar(2, 3)).toBe(5);
});
La prueba corre rápido, no necesita red ni navegador, y documenta qué debe hacer la unidad con cada conjunto de entradas.
La estructura básica de Jest
Jest ofrece funciones globales para describir y ejecutar pruebas. La estructura típica separa qué se quiere probar, el caso concreto y la comprobación.
describe('sumar', () => {
test('suma valores positivos', () => {
expect(sumar(1, 2)).toBe(3);
});
test('suma valores negativos', () => {
expect(sumar(-1, -2)).toBe(-3);
});
});
describe agrupa casos relacionados y convierte la salida en una lista legible de comportamiento esperado.
Qué matchers usar
Jest incluye matchers para distintos tipos de resultado. Los más habituales:
toBepara valores exactos.toEqualpara objetos y arreglos.toHaveLengthpara tamaños.toThrowpara funciones que lanzan errores.toContainpara revisar elementos dentro de una colección.
test('construye el usuario correctamente', () => {
const usuario = crearUsuario({ nombre: 'Ana', edad: 30 });
expect(usuario).toEqual({ nombre: 'Ana', edad: 30 });
});
test('rechaza edades inválidas', () => {
expect(() => validarEdad(-1)).toThrow('Edad inválida');
});
Elegir el matcher correcto hace que un fallo describa el problema exacto en lugar de un booleano genérico.
Aislar dependencias con mocks
Una unidad no siempre es pura. Puede llamar a una API, leer el reloj o consultar una base de datos. En una prueba unitaria esas dependencias se reemplazan por versiones simuladas que devuelven valores controlados.
jest.mock('./servicioUsuarios');
test('carga y transforma usuarios', async () => {
servicioUsuarios.obtener.mockResolvedValue([
{ nombre: 'Luis', edad: 25 },
{ nombre: 'María', edad: 30 }
]);
const resultado = await cargarUsuarios();
expect(resultado).toHaveLength(2);
expect(servicioUsuarios.obtener).toHaveBeenCalledTimes(1);
});
Con mockResolvedValue se controla la respuesta, y con toHaveBeenCalledTimes se verifica que la unidad interactuó con su dependencia de la forma esperada.
Lo que no debe ir en una prueba unitaria
Una prueba unitaria pierde sentido cuando:
- Depende de la red o de un servidor real.
- Usa temporizadores que hacen el resultado impredecible.
- Prueba varias unidades al mismo tiempo y dificulta saber qué falló.
- Repite la implementación en lugar de verificar el comportamiento.
Si una prueba depende de una base de datos concreta o de movimientos del usuario, quizá ya no es unitaria.
Cobertura como señal, no como meta
Jest puede generar reportes de cobertura sobre cuántas líneas, ramas y funciones se ejecutaron.
jest --coverage
La cobertura muestra qué código quedó sin probar, pero un porcentaje alto no garantiza buenas pruebas. Más útil que perseguir el cien por ciento es cubrir los caminos críticos: validaciones, condiciones límite, errores y casos de borde.
Consideraciones
Las pruebas unitarias no reemplazan a las pruebas de integración ni de extremo a extremo, pero son la primera red de seguridad: rápidas, deterministas y ejecutables en cada cambio. Con Jest, la clave está en probar comportamiento, aislar dependencias y elegir matchers que hagan los fallos fáciles de leer.
© Arturo Juárez Monroy