Cada framework de pruebas que has utilizado, ya sea Jest, Mocha o node:test, se basa en una idea simple: defines lo que esperas y lanzas un error si la realidad no coincide. Node.js incluye esa idea como un módulo incorporado llamado assert: sin instalación, sin dependencias, solo lo importas y empiezas a validar suposiciones.
El módulo assert sirve para comprobaciones rápidas en scripts, pruebas unitarias simples y validación de respuestas HTTP. También ayuda a entender qué hace realmente una aserción antes de usar un framework más grande. En esta guía verás cómo importar assert, comparar valores, validar objetos, probar errores, manejar código asíncrono y aplicar las mismas ideas a pruebas de API.
Qué hace el módulo assert
Una aserción declara que algo debe ser verdadero para que el programa sea correcto.
Por ejemplo:
assert.strictEqual(total, 100);
Esto significa: "total debe ser exactamente 100".
Si la condición se cumple, no pasa nada. Si falla, Node.js lanza un AssertionError.
Importa siempre la versión estricta:
const assert = require('node:assert/strict');
// Con ES modules:
// import assert from 'node:assert/strict';
La aserción más básica verifica que un valor sea truthy:
const user = getUser(42);
assert(user, 'getUser debe devolver un objeto de usuario');
El segundo argumento es el mensaje de error. Úsalo siempre. Un fallo con contexto es mucho más útil que un AssertionError genérico.
Comprender esto también ayuda cuando pasas a aserciones de API en herramientas especializadas.
Usa modo estricto, no modo legado
assert tiene dos modos:
const looseAssert = require('node:assert');
const strictAssert = require('node:assert/strict');
El modo legado usa igualdad flexible (==) en métodos como equal:
const assert = require('node:assert');
assert.equal(1, '1'); // pasa
Esto pasa porque JavaScript convierte tipos automáticamente. En pruebas, eso suele ocultar errores.
El modo estricto usa igualdad estricta (===):
const assert = require('node:assert/strict');
assert.equal(1, '1'); // lanza AssertionError
En la práctica:
const looseAssert = require('node:assert');
looseAssert.equal(1, '1'); // pasa, pero puede ser peligroso
const assert = require('node:assert/strict');
assert.equal(1, '1'); // falla, como debería
Recomendación: usa siempre node:assert/strict. En este modo, assert.equal se comporta como assert.strictEqual.
Comparar valores primitivos con strictEqual
Usa assert.strictEqual(actual, expected) para números, strings, booleanos y otros valores primitivos.
const assert = require('node:assert/strict');
function priceWithTax(price, rate) {
return price + price * rate;
}
assert.strictEqual(
priceWithTax(100, 0.08),
108,
'el cálculo del impuesto debe sumar un 8%'
);
assert.strictEqual(
typeof priceWithTax(100, 0.08),
'number',
'el resultado debe ser un número'
);
Para comprobar que dos valores no sean iguales, usa notStrictEqual:
const before = getCacheKey();
refreshCache();
const after = getCacheKey();
assert.notStrictEqual(
before,
after,
'la clave de caché debe cambiar después de la actualización'
);
No uses strictEqual para comparar objetos o arrays por contenido. En JavaScript, dos objetos con la misma estructura siguen siendo referencias distintas:
assert.strictEqual({ id: 1 }, { id: 1 }); // falla
Para eso necesitas igualdad profunda.
Comparar objetos y arrays con deepStrictEqual
Usa assert.deepStrictEqual(actual, expected) para comparar estructuras completas.
const assert = require('node:assert/strict');
function buildOrder(id, items) {
return {
id,
items,
status: 'pending'
};
}
assert.deepStrictEqual(
buildOrder(7, ['keyboard', 'mouse']),
{
id: 7,
items: ['keyboard', 'mouse'],
status: 'pending'
},
'el objeto de pedido debe coincidir con la forma esperada'
);
Este método compara claves, valores y tipos de forma recursiva.
Por ejemplo, esto falla:
assert.deepStrictEqual(
{ id: 7 },
{ id: '7' },
'el id debe ser numérico'
);
Falla porque 7 y '7' no tienen el mismo tipo. Esa estrictez es útil: detecta cambios silenciosos en tus datos.
Usa deepStrictEqual para:
- objetos devueltos por funciones
- arrays
- cuerpos JSON de APIs
- estructuras anidadas
- fixtures esperados
Ejemplo con respuesta JSON:
assert.deepStrictEqual(
body.user,
{
id: 101,
name: 'Dana Lee',
active: true
},
'el usuario debe coincidir con la respuesta esperada'
);
Si tienes muchos casos de entrada, puedes escalar este patrón con pruebas parametrizadas o datos externos. Esta guía sobre pruebas de API basadas en datos con CSV y JSON explica ese enfoque.
Cuando deepStrictEqual falla, Node.js muestra un diff con las propiedades distintas. Para objetos grandes, ese diff suele ser mucho más útil que escribir múltiples strictEqual campo por campo.
Validar existencia y formato con ok y match
No todas las pruebas necesitan comparar un objeto completo. A veces solo quieres validar que un valor exista o que tenga cierto formato.
Usa assert.ok(value) para comprobar valores truthy:
assert.ok(user, 'el usuario debe existir');
assert.ok(user.email, 'el usuario debe incluir email');
assert.ok(items.length > 0, 'la lista de items no debe estar vacía');
Usa assert.match(string, regexp) para validar strings con expresiones regulares:
const assert = require('node:assert/strict');
function generateOrderId() {
return 'ORD-' + Date.now();
}
const id = generateOrderId();
assert.match(
id,
/^ORD-\d+$/,
'el id de pedido debe ser ORD- seguido de dígitos'
);
assert.ok(
id.length > 4,
'el id de pedido no debe estar vacío'
);
También existe assert.doesNotMatch:
assert.doesNotMatch(
username,
/\s/,
'el username no debe contener espacios'
);
Este patrón es especialmente útil en pruebas de API, donde algunos valores cambian en cada respuesta:
- timestamps
- IDs generados
- tokens
- UUIDs
- URLs firmadas
En esos casos, valida la forma, no el valor exacto.
Probar que una función lanza errores con throws
A veces el comportamiento correcto es fallar. Para eso usa assert.throws(fn, expectedError).
const assert = require('node:assert/strict');
function parsePort(value) {
const port = Number(value);
if (!Number.isInteger(port) || port < 1 || port > 65535) {
throw new RangeError('port must be an integer between 1 and 65535');
}
return port;
}
Valida que una entrada inválida lance el tipo correcto de error:
assert.throws(
() => parsePort('70000'),
RangeError,
'un puerto fuera de rango debe lanzar RangeError'
);
También puedes validar el mensaje con una expresión regular:
assert.throws(
() => parsePort('abc'),
/must be an integer/,
'un puerto no numérico debe lanzar un error descriptivo'
);
Y puedes comprobar que una entrada válida no lance error:
assert.doesNotThrow(
() => parsePort('8080'),
'un puerto válido no debe lanzar un error'
);
Punto importante: pasa una función, no el resultado de ejecutarla.
Correcto:
assert.throws(() => parsePort('70000'), RangeError);
Incorrecto:
assert.throws(parsePort('70000'), RangeError);
En el segundo caso, parsePort('70000') se ejecuta antes de que assert.throws pueda capturar el error.
Probar promesas rechazadas con rejects
En código asíncrono, una promesa rechazada equivale a un error lanzado. Para eso usa:
assert.rejectsassert.doesNotReject
Ambos devuelven promesas, así que debes usar await.
const assert = require('node:assert/strict');
async function fetchUser(id) {
if (typeof id !== 'number') {
throw new TypeError('id must be a number');
}
return {
id,
name: 'Dana Lee'
};
}
async function runTests() {
await assert.rejects(
fetchUser('not-a-number'),
TypeError,
'el id de tipo string debe ser rechazado'
);
await assert.doesNotReject(
fetchUser(101),
'un id válido debe resolverse correctamente'
);
}
runTests();
También puedes pasar una función async:
await assert.rejects(
async () => fetchUser('not-a-number'),
TypeError,
'debe rechazar ids no numéricos'
);
No olvides await. Sin await, la prueba puede terminar antes de que la aserción se resuelva, y el fallo aparecerá como un rechazo no manejado en lugar de un error claro.
Usar assert para probar respuestas de API
assert funciona bien para validar una solicitud HTTP simple: código de estado, headers y cuerpo JSON.
Ejemplo con fetch:
const assert = require('node:assert/strict');
async function testGetUser() {
const res = await fetch('https://api.example.com/users/101');
assert.strictEqual(
res.status,
200,
'GET /users/101 debe devolver 200'
);
const body = await res.json();
assert.strictEqual(
typeof body.id,
'number',
'el id debe ser un número'
);
assert.strictEqual(
body.id,
101,
'el id debe coincidir con el usuario solicitado'
);
assert.ok(
body.name,
'la respuesta debe incluir un nombre'
);
assert.ok(
Array.isArray(body.roles),
'roles debe ser un array'
);
}
testGetUser().then(
() => console.log('Prueba de API superada'),
(err) => {
console.error('Prueba de API fallida:', err.message);
process.exitCode = 1;
}
);
También puedes validar headers:
assert.match(
res.headers.get('content-type'),
/application\/json/,
'la respuesta debe ser JSON'
);
Y validar una estructura parcial del cuerpo:
assert.deepStrictEqual(
{
id: body.id,
active: body.active
},
{
id: 101,
active: true
},
'los campos principales del usuario deben coincidir'
);
Este patrón es útil para scripts pequeños y comprobaciones rápidas. Para una suite real de APIs, normalmente necesitarás más cosas:
- gestión de entornos
- autenticación reutilizable
- reintentos
- ejecución en CI/CD
- reportes
- escenarios con múltiples requests
- datos de prueba
Para ese siguiente paso, revisa estas guías sobre cómo escribir scripts de prueba automatizados y el framework de automatización de API pytest.
Si no quieres construir manualmente todo el arnés de pruebas, Apidog te permite definir solicitudes de API y adjuntar aserciones visuales sobre códigos de estado, encabezados y campos JSON sin escribir todo el código de aserción. También puedes encadenar solicitudes en escenarios automatizados, ejecutarlos en CI/CD y usar scripts personalizados cuando necesites más control. Puedes descargar Apidog y usarlo gratis. Junto con Apidog, el módulo assert de Node.js cubre tanto comprobaciones rápidas como suites más completas.
Preguntas frecuentes
¿Necesito instalar el módulo assert?
No. assert está incorporado en Node.js.
Impórtalo así:
const assert = require('node:assert/strict');
O, si usas ES modules:
import assert from 'node:assert/strict';
No necesitas instalar ningún paquete npm. El prefijo node: indica explícitamente que estás cargando un módulo central de Node.js.
¿Cuál es la diferencia entre assert.equal y assert.strictEqual?
En modo legado, assert.equal usa igualdad flexible (==) y assert.strictEqual usa igualdad estricta (===).
En modo estricto:
const assert = require('node:assert/strict');
assert.equal se comporta igual que assert.strictEqual.
Recomendación: usa siempre node:assert/strict para evitar que la coerción de tipos haga pasar una prueba por accidente.
¿Cuándo debo usar deepStrictEqual en lugar de strictEqual?
Usa strictEqual para valores primitivos:
assert.strictEqual(statusCode, 200);
assert.strictEqual(typeof user.id, 'number');
assert.strictEqual(user.active, true);
Usa deepStrictEqual para objetos y arrays:
assert.deepStrictEqual(user.roles, ['admin', 'editor']);
assert.deepStrictEqual(response.body, expectedBody);
strictEqual compara referencias. Dos objetos separados con el mismo contenido no son iguales por referencia.
¿Debo usar assert o un framework como Jest?
Depende del caso.
Usa assert para:
- scripts rápidos
- pruebas pequeñas
- validaciones internas
- aprender fundamentos de testing
- comprobar respuestas HTTP simples
Usa un framework cuando necesites:
- organización de suites
- hooks como
beforeEachyafterEach - mocks
- reportes
- watch mode
- integración con herramientas de cobertura
Node.js también incluye node:test, un runner incorporado que combina muy bien con assert y no requiere dependencias externas.
¿Cómo afirmo que una función asíncrona se rechaza?
Usa assert.rejects con await:
await assert.rejects(
fetchUser('invalid-id'),
TypeError,
'debe rechazar ids inválidos'
);
También puedes validar el mensaje:
await assert.rejects(
fetchUser('invalid-id'),
/id must be a number/,
'debe devolver un mensaje de error claro'
);
Sin await, la aserción puede no ejecutarse correctamente antes de que termine la prueba.
Top comments (0)