Prueba tus rutas de extremo a extremo con node:test y fetch en un puerto efímero, con cada prueba recibiendo su propia base de datos SQLite en memoria.
Abrir esta lección en KodokonNode 20 incluye todo lo que necesitas: node:test como runner, node:assert/strict para las aserciones, el fetch global como cliente HTTP. Cero dependencias de prueba. Y aquí es donde la arquitectura de la primera lección da sus frutos: createApp({ db }) acepta una base de datos inyectada, así que cada prueba puede montar una API completa y aislada en unos pocos milisegundos.
node --test
node --test --watchPara probar las rutas de extremo a extremo, no hace falta simular Express: monta un servidor real en el puerto 0 (el sistema asigna un puerto libre) y luego atácalo con fetch. Ejercitas exactamente lo que verá un cliente real: enrutamiento, middlewares, serialización, códigos de estado. Es el espíritu de supertest, sin la dependencia.
import { once } from 'node:events';
export async function startTestServer(app) {
const server = app.listen(0);
await once(server, 'listening');
const { port } = server.address();
const url = `http://127.0.0.1:${port}`;
const close = () =>
new Promise((resolve) => {
server.close(resolve);
});
return { url, close };
}La base de datos de pruebas: SQLite en memoria (:memory:). Cada prueba construye su propia base de datos nueva y en blanco mediante createDb, que aplica el esquema, y luego la descarta al salir: sin datos compartidos entre pruebas, sin script de limpieza. t.after garantiza que el servidor se cierre incluso cuando una aserción falla.
import test from 'node:test';
import assert from 'node:assert/strict';
import { createDb } from '../src/db/connection.js';
import { createApp } from '../src/app.js';
import { startTestServer } from './helpers.js';
test('POST /api/users creates a user', async (t) => {
const db = createDb(':memory:');
const app = createApp({ db });
const server = await startTestServer(app);
t.after(() => server.close());
const res = await fetch(`${server.url}/api/users`, {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
email: 'ada@example.com',
name: 'Ada',
}),
});
assert.equal(res.status, 201);
const body = await res.json();
assert.equal(body.email, 'ada@example.com');
});app.listen(0)?:memory: creada en cada prueba?t.after en lugar de al final del cuerpo de la prueba?