Artículo original: How to Write Tests Using the Node.js Test Runner and mongodb-memory-server
Recientemente migré algunas pruebas de Jest al ejecutor de pruebas de Node.js en dos de mis proyectos que usan MongoDB. En uno de esos proyectos, el tiempo de ejecución de las pruebas fue reducido de 107 segundos a 25 segundos (captura de pantalla abajo). En el otro proyecto, el tiempo de ejecución de las pruebas fue reducido cerca de un 66%.

Decidí compartirte cómo pude implementarlo. Pienso que te será de utilidad, ya que es más rentable (en términos de reducir dinero gastado en ejecutar pruebas en CI/CD), y también mejora tu experiencia de desarrollo.
Tabla de Contenidos
Pre-requisitos
Para seguir esta guía, deberías de tener experiencia trabajando con Node.js, MongoDB y Mongoose (o cualquier otro mapeador de datos de objetos de MongoDB). Deberías también tener instalado Node.js (al menos la versión 20.18.2) y MongoDB (Compass la versión GUI) en tu computadora.
El Ejecutor de Pruebas de Node.js
El ejecutor de pruebas de Node.js fue introducido como una característica experimental en la versión 18 de Node.js. Se volvió disponible oficialmente en la versión 20. Te da la habilidad de:
- Ejecutar pruebas
- Reportar resultados de las pruebas
- Reportar cobertura de las pruebas (todavía experimental en la versión 23)
Es una buena idea el usar el ejecutor de pruebas incorporado cuando se escriban pruebas en Node.js porque significa que tienes que usar menos dependencias externas. No necesitas instalar una librería externa (y sus dependencias entre pares) para ejecutar las pruebas.
El mejor ejecutor incorporado también es el más rápido. Basado en mi experiencia usándolo en dos proyectos (los cuales usaron Jest), vi mejoras de al menos una reducción del 66% en el tiempo que tomó ejecutar las pruebas completamente.
Y a diferencia de otros frameworks o librerías de pruebas, el ejecutor de pruebas de Node.js fue construido especialmente para proyectos de Node.js. No trata de acomodar las especificaciones de otros entornos de programación como el navegador. Las especificaciones de Node.js son su principal y única prioridad.
El Servidor en memoria de MongoDB
Para las pruebas que involucran el hacer peticiones a una base de datos, algunos desarrolladores prefieren imitar las peticiones para evitar hacer peticiones a una base de datos real. Hacen esto porque hacer una petición a una base de datos real requiere un montón de configuraciones que puede costar tiempo y recursos.
Escribir y solicitar datos usando una base de datos real es más lento comparado con escribir y solicitar datos de la memoria. Cuando se ejecutan pruebas automatizadas, usando un servidor de MongoDB real será más lento que usar un servidor de base de datos en memoria, y ahí es donde mongodb-memory-server se vuelve útil.

Según su documentación, mongodb-memory-server crea y comienza un servidor de MongoDB real de forma programática desde dentro de Node.js, pero usa una base de datos en memoria por defecto. También te permite conectar el servidor de base de datos que crea usando tu mapeador de datos de objetos preferido tales como Mongoose, Prisma, o TypeORM. En esta guía, usaremos Mongoose (v.8.9.6).
Ya que los datos almacenados por mongodb-memory-server reside en la memoria por defecto, es más rápido leer y escribir en él que cuando se usa una base de datos real. mongodb-memory-server también es más fácil de configurar. Estos beneficios lo hace una buena elección para usarlo como un servidor de base de datos para escribir pruebas.
Nota: asegúrate de instalar la versión 9.1.6 de mongodb-memory-server para seguir esta guía. La versión 10 actualmente tiene problemas con limpiar los recursos después que se hacen las pruebas. Mira este problema con el título "Node forking will include any --import
from the original command".
El problema ha sido resuelto al tiempo de escribir este artículo, pero el arreglo no ha sido fusionado para las instalaciones.
Cómo escribir las Pruebas
Ahora te guiaré a través de los siguientes pasos para que comiences a escribir las pruebas:
- Configurar el proyecto
- Configurar el esquema de Mongoose
- Configurar los servicios
- Configurar las pruebas
- Escribir las pruebas
- Pasar las pruebas
- Usa TypeScript (Opcional)
1. Configurar el Proyecto
Creé un repositorio de Github para facilitarte que sigas esta guía. Clona este repositorio en nodejs-test-runner-mongoose y dirígete a la rama 01-setup
.
En 01-setup
, las dependencias para el proyecto están el archivo package.json
. Instala las dependencias usando el comando npm install
para configurar el proyecto. Asegúrate de que la configuración esté completa y correcta, ejecuta el comando node .
en la terminal de tu proyecto. Deberías ver tu versión de Node.js como una salida en la terminal.
# instala las dependencias
npm install
...
# ejecuta el comando node
node .
# la salida
You are running Node.js v22.13.1
2. Configurar el Esquema de Mongoose
Configuraremos el esquema para dos colecciones (Task y User) en la rama 02-setup-schema
usando Mongoose. Los archivos task/model.mjs
y user/model.mjs
contienen el esquema para las colecciones Task y User, respectivamente. También configuraremos una conexión de base de datos en index.mjs
para asegurar que la configuración del esquema funcione correctamente.
No iré en detalle sobre los modelos y esquemas de Mongoose en este artículo porque están fuera de su alcance.
Cuando ejecutas el comando node .
después de implementar los cambios en 02-setup-schema
, deberías de ver un resultado similar en la consola como en el fragmento de abajo:
node .
You are running Node.js v22.13.1
Created user with id 679f1d7f73fbeaf23b2007df
Created task "Task title" for user with id "679f1d7f73fbeaf23b2007df"
Puedes ver las diferencias entre 01-setup
y 02-setup-schema
a través de la diferencia 01-setup <> 02-setup-schema en Github.
3. Configurar los Servicios
Luego, creamos los archivos de servicio (task/service.mjs
y user/service.mjs
) en la rama 03-setup-services
. Ambos archivos actualmente contienen funciones vacías en el que escribiremos las pruebas más tarde. Estas funciones contendrán la lógica de negocio y también se comunicará con la base de datos. Estamos usando comentarios de JSDoc para escribir parámetros y regresar valores.
Haz clic en la diferencia de 02-setup-schema <> 03-setup-services para ver los cambios de código entre 02-setup-schema
y 03-setup-services
.
4. Configurar las Pruebas
En la rama 04-set-up-tests
, configuramos la base de código para ejecutar las pruebas. Creamos test.setup.mjs
el cual contiene el código que será ejecutado antes de que cada archivo de prueba se ejecute.
En test.setup.mjs
, la función connect
crea un servidor de MongoDB en memoria y lo conecta con Mongoose para ejecutar las pruebas. La función closeDatabase
cierra la conexión de la base de datos y limpia todos los recursos para liberar memoria.
Las funciones connect
y closeDatabase
se ejecutan en el hook t.before
y en el hook t.after
respectivamente. Esto asegura eso, antes que un archivo test se ejecute, una conexión de base de datos se establece a través t.before
. Luego de que se hayan ejecutado las pruebas del archivo, la conexión de la base de datos se cae y los recursos usados se limpian a través de t.after
.
En package.json
, actualizaremos el script de npm test
a node --test --import ./test.setup.mjs
. Este comando asegura que Módulo Es test.setup.mjs
se pre-cargue y se ejecute a través del comando --import
del CLI antes de que cada archivo de prueba se ejecute.
Luego crearemos los archivos de prueba con pruebas vacías en las carpetas __tests__
para user
y task
. Después de implementar los nuevos cambios en 04-set-up-tests, ejecutar el script test
con npm run test
debería de mostrar la salida similar al fragmento de abajo:
npm run test
> nodejs-test-runner-mongoose@1.0.0 test
> node --test --import ./test.setup.mjs
...
ℹ tests 8
ℹ suites 5
ℹ pass 8
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 941.768873
Todas las pruebas actualmente pasan porque no hay aserciones que fallen. Escribiremos las pruebas con aserciones en la siguiente sección.
5. Escribir Pruebas
Ahora es tiempo de escribir las pruebas para las funciones en los archivos de service en la rama 05-write-tests
. Estamos usando la librería de aserción de Node.js para asegurar que los valores regresados de las funciones sean lo que esperamos. Puedes ver las pruebas que hemos escrito cuando comparas las diferencias entre 04-set-up-tests y 05-write-tests.
Cuando el script tests
se ejecute, todas las pruebas fallan porque no hemos escritos las funciones en los archivos de service todavía. Debería de ver una salida similar al fragmento de abajo cuando ejecutes el script test
:
npm run test
> nodejs-test-runner-mongoose@1.0.0 test
> node --test --import ./test.setup.mjs
...
ℹ tests 8
ℹ suites 5
ℹ pass 0
ℹ fail 8
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1202.031961
6. Pasar las Pruebas
En 06-pass-tests
, escribimos las funciones en los archivos de service que pasen las pruebas. Solamente 6 de 7 pruebas pasan cuando el script test
se ejecuta porque salteamos la prueba para la función getById
en user/service.mjs
con t.skip
. No hemos terminado la función getById
en user/service.mjs
. Supuse que podríamos dejarlo como ejercicio.
Cuando ejecutas el script test
, deberías obtener una salida similar en la terminal como el de abajo:
ℹ tests 7
ℹ suites 4
ℹ pass 6
ℹ fail 0
ℹ cancelled 0
ℹ skipped 1
ℹ todo 0
ℹ duration_ms 1287.564918
Puedes ver el código que escribimos para pasar las pruebas en los cambios de código entre 05-write-tests y 06-pass-tests.
7. Usa TypeScript (Opcional)
Si tu intención es ejecutar las pruebas con TypeScript, puedes cambiar a la rama 07-with-typescript
. Necesitas tener Node.js >=22.6.0
instalado porque estamos usando la opción --experimental-strip-types
en el test
. Para configurar las pruebas que se ejecuten con TypeScript, sigue los siguientes pasos:
- Instala TypeScript usando el comando
npm install typescript --save-dev
- Instala tsx usando el comando
npm install tsx
- Crea un archivo predeterminado
tsconfig.json
en la raíz del proyecto usando el comandonpx tsc --init
En package.json
, actualiza el script test
a esto:
"test": "node --test --experimental-strip-types --import tsx --import ./test.setup.mjs"
--experimental-strip-types
ayuda a eliminar tipos antes de cada archivo de prueba se ejecute.
Pre-cargar tsx
con el --import
ayuda a ejecutar el archivo de TypeScript. Sin él, el ejecutor de pruebas no será capaz de encontrar archivos importados sin la extensión .ts
. Por ejemplo, user/model.ts
importado con el fragmento de código de abajo no será encontrado.
import { UserModel } from "./model";
El resto de los cambios desde 06-pass-tests a 07-with-typescript involucran actualizar los tipos, cambiar las extensiones de archivo de .mjs
a .ts
y actualizar las declaraciones import.
Conclusión
En esta guía, has aprendido cómo usar el ejecutor de pruebas incorporado de Node.js y por qué es frecuentemente una mejor elección sobre otras librerías y frameworks de pruebas. También has aprendido cómo usar mongodb-memory-server como un reemplazo de un servidor real de MongoDB, así también como por qué es una buena idea usarlo en vez de un servidor real de MongoDB para las pruebas.
Lo más importante, has aprendido cómo configurar y ejecutar las pruebas en Node.js usando el ejecutor de pruebas de Node.js y mongodb-memory-server. Ahora deberías de saber cómo configurar tus proyectos para que ejecuten las pruebas si usas TypeScript.
Si encuentras útil a este repositorio nodejs-test-runner-mongoose, por favor dale una estrella. Me anima mucho. Gracias.