En este módulo, aprenderemos a realizar pruebas unitarias en aplicaciones Node.js utilizando Mocha y Chai. Las pruebas unitarias son fundamentales para asegurar que cada parte de tu aplicación funcione correctamente de manera aislada.
¿Qué es Mocha?
Mocha es un framework de pruebas para Node.js que facilita la escritura de pruebas asíncronas y proporciona una estructura flexible para organizar y ejecutar pruebas.
Características de Mocha:
- Soporte para pruebas asíncronas.
- Salida de informes personalizable.
- Funciona con cualquier biblioteca de aserciones.
¿Qué es Chai?
Chai es una biblioteca de aserciones que se puede usar con cualquier framework de pruebas. Proporciona una sintaxis legible y expresiva para escribir aserciones.
Características de Chai:
- Soporte para diferentes estilos de aserciones: TDD (Test-Driven Development) y BDD (Behavior-Driven Development).
- Extensible con plugins.
Instalación de Mocha y Chai
Para comenzar, necesitamos instalar Mocha y Chai en nuestro proyecto. Puedes hacerlo utilizando npm:
Configuración de Mocha
-
Crear una estructura de directorios para las pruebas:
mkdir test
-
Agregar un script de prueba en
package.json
:{ "scripts": { "test": "mocha" } }
Escribiendo tu Primera Prueba
Vamos a escribir una prueba simple para una función que suma dos números. Primero, creamos un archivo sum.js
en el directorio src
:
Ahora, creamos un archivo de prueba sum.test.js
en el directorio test
:
// test/sum.test.js const chai = require('chai'); const expect = chai.expect; const sum = require('../src/sum'); describe('Función sum', () => { it('debería devolver la suma de dos números', () => { const result = sum(2, 3); expect(result).to.equal(5); }); it('debería devolver un número negativo si la suma es negativa', () => { const result = sum(-2, -3); expect(result).to.equal(-5); }); });
Explicación del Código:
describe
: Agrupa pruebas relacionadas. En este caso, estamos agrupando pruebas para la funciónsum
.it
: Define una prueba individual. Cada prueba tiene una descripción y una función que contiene las aserciones.expect
: Es una función de Chai que se usa para hacer aserciones. En este caso, estamos verificando que el resultado desum(2, 3)
sea igual a5
.
Ejecutando las Pruebas
Para ejecutar las pruebas, simplemente corre el siguiente comando en tu terminal:
Deberías ver una salida similar a esta:
Función sum ✓ debería devolver la suma de dos números ✓ debería devolver un número negativo si la suma es negativa 2 passing (10ms)
Pruebas Asíncronas
Mocha facilita la escritura de pruebas asíncronas. Supongamos que tenemos una función que lee un archivo de manera asíncrona:
// src/readFile.js const fs = require('fs'); function readFile(filePath, callback) { fs.readFile(filePath, 'utf8', (err, data) => { if (err) return callback(err); callback(null, data); }); } module.exports = readFile;
Podemos escribir una prueba para esta función de la siguiente manera:
// test/readFile.test.js const chai = require('chai'); const expect = chai.expect; const readFile = require('../src/readFile'); const fs = require('fs'); const path = require('path'); describe('Función readFile', () => { it('debería leer el contenido de un archivo', (done) => { const filePath = path.join(__dirname, 'test.txt'); fs.writeFileSync(filePath, 'Hola, mundo!'); readFile(filePath, (err, data) => { expect(err).to.be.null; expect(data).to.equal('Hola, mundo!'); fs.unlinkSync(filePath); // Limpieza done(); }); }); });
Explicación del Código:
done
: Es una función que Mocha proporciona para manejar pruebas asíncronas. Llamamos adone
cuando la prueba ha terminado.fs.writeFileSync
yfs.unlinkSync
: Estas funciones se usan para crear y eliminar un archivo de prueba.
Ejercicios Prácticos
Ejercicio 1: Prueba de una Función de Multiplicación
- Crea una función
multiply
que multiplique dos números. - Escribe pruebas para verificar que la función
multiply
funciona correctamente.
Solución:
// test/multiply.test.js const chai = require('chai'); const expect = chai.expect; const multiply = require('../src/multiply'); describe('Función multiply', () => { it('debería devolver el producto de dos números', () => { const result = multiply(2, 3); expect(result).to.equal(6); }); it('debería devolver cero si uno de los números es cero', () => { const result = multiply(0, 5); expect(result).to.equal(0); }); });
Ejercicio 2: Prueba de una Función Asíncrona
- Crea una función
fetchData
que simule una llamada a una API y devuelva datos después de 1 segundo. - Escribe pruebas para verificar que la función
fetchData
funciona correctamente.
Solución:
// src/fetchData.js function fetchData(callback) { setTimeout(() => { callback(null, { data: 'Datos de la API' }); }, 1000); } module.exports = fetchData;
// test/fetchData.test.js const chai = require('chai'); const expect = chai.expect; const fetchData = require('../src/fetchData'); describe('Función fetchData', () => { it('debería devolver datos después de 1 segundo', (done) => { fetchData((err, data) => { expect(err).to.be.null; expect(data).to.deep.equal({ data: 'Datos de la API' }); done(); }); }); });
Conclusión
En este módulo, hemos aprendido a realizar pruebas unitarias en Node.js utilizando Mocha y Chai. Hemos cubierto la instalación, configuración y escritura de pruebas tanto síncronas como asíncronas. Además, hemos proporcionado ejercicios prácticos para reforzar los conceptos aprendidos.
En el siguiente módulo, exploraremos las pruebas de integración y cómo asegurar que diferentes partes de tu aplicación funcionen correctamente juntas.
Curso de Node.js
Módulo 1: Introducción a Node.js
Módulo 2: Conceptos Básicos
Módulo 3: Sistema de Archivos y E/S
Módulo 4: HTTP y Servidores Web
- Creando un Servidor HTTP Simple
- Manejo de Solicitudes y Respuestas
- Sirviendo Archivos Estáticos
- Enrutamiento
Módulo 5: NPM y Gestión de Paquetes
- Introducción a NPM
- Instalación y Uso de Paquetes
- Creación y Publicación de Paquetes
- Versionado Semántico
Módulo 6: Framework Express.js
- Introducción a Express.js
- Configuración de una Aplicación Express
- Middleware
- Enrutamiento en Express
- Manejo de Errores
Módulo 7: Bases de Datos y ORMs
- Introducción a las Bases de Datos
- Usando MongoDB con Mongoose
- Usando Bases de Datos SQL con Sequelize
- Operaciones CRUD
Módulo 8: Autenticación y Autorización
- Introducción a la Autenticación
- Usando Passport.js
- Autenticación JWT
- Control de Acceso Basado en Roles
Módulo 9: Pruebas y Depuración
- Introducción a las Pruebas
- Pruebas Unitarias con Mocha y Chai
- Pruebas de Integración
- Depuración de Aplicaciones Node.js
Módulo 10: Temas Avanzados
- Módulo Cluster
- Hilos de Trabajo
- Optimización del Rendimiento
- Construcción de APIs RESTful
- GraphQL con Node.js
Módulo 11: Despliegue y DevOps
- Variables de Entorno
- Usando PM2 para la Gestión de Procesos
- Desplegando en Heroku
- Integración y Despliegue Continuos