Creación de Datos Simulados con la Librería Faker.js

Clase 9 de 23Curso de Pruebas Unitarias en Angular

Resumen

La creación de datos simulados o "mocking" es una técnica fundamental en el desarrollo de software que permite probar aplicaciones de manera eficiente. Esta práctica no solo facilita la creación de escenarios de prueba controlados, sino que también mejora la calidad del código al permitir validar comportamientos específicos sin depender de datos reales.

¿Qué es el mocking y por qué es importante?

El mocking es una estrategia utilizada en pruebas unitarias para crear datos emulados que sirven para simular escenarios y probar comportamientos específicos del código. En lugar de utilizar datos reales, que pueden ser difíciles de obtener o manipular, creamos datos ficticios que cumplen con la estructura necesaria para nuestras pruebas.

Esta técnica es particularmente útil cuando:

  • Necesitamos probar escenarios específicos que serían difíciles de reproducir con datos reales
  • Queremos aislar la funcionalidad que estamos probando de dependencias externas
  • Buscamos hacer pruebas más rápidas y predecibles
  • Necesitamos reutilizar configuraciones de prueba en diferentes contextos

A menudo, la creación manual de estos datos simulados puede resultar en código más extenso que las propias pruebas, lo que no es ideal. Por eso, es importante sistematizar la generación de estos datos.

¿Cómo implementar mocking eficiente con Faker.js?

Para implementar un sistema de mocking eficiente, podemos utilizar librerías especializadas como Faker.js, que nos permite generar datos realistas de manera programática.

Instalación y configuración de Faker.js

Faker.js es una librería que facilita la creación de datos simulados para diversos escenarios:

// Instalación de Faker.js
npm install @faker-js/faker

Es importante asegurarse de instalar la versión correcta (@faker-js/faker), ya que existe otra librería con nombre similar que podría tener problemas de seguridad.

Creación de funciones de mocking reutilizables

Una buena práctica es crear funciones específicas para generar los datos simulados que necesitamos. Esto nos permite:

  1. Centralizar la lógica de creación de datos
  2. Reutilizar el código en diferentes pruebas
  3. Mantener consistencia en los datos generados
  4. Facilitar la modificación de casos específicos

Veamos un ejemplo de implementación para productos:

// product.mock.js
import { faker } from '@faker-js/faker';
import { Product } from './product.model';

export const generateFakeProduct = (data = {}) => {
  const fakeProduct = {
    id: faker.string.uuid(),
    title: faker.commerce.productName(),
    price: parseFloat(faker.commerce.price()),
    image: faker.image.url(),
    category: {
      id: faker.string.uuid(),
      name: faker.commerce.department(),
      slug: faker.helpers.slugify(faker.commerce.department().toLowerCase())
    }
  };
  
  // Permite sobrescribir cualquier propiedad con datos específicos
  return { ...fakeProduct, ...data };
};

La clave de esta implementación es que permite generar datos aleatorios por defecto, pero también sobrescribir propiedades específicas cuando sea necesario para casos de prueba particulares.

Uso práctico en pruebas unitarias

Una vez implementada nuestra función de generación de datos, podemos utilizarla en nuestras pruebas:

// En nuestro archivo de pruebas
import { generateFakeProduct } from './product.mock';

describe('ShoppingCart', () => {
  it('debería agregar un producto con precio cero', () => {
    // Generamos un producto con precio específico
    const product = generateFakeProduct({ price: 0 });
    
    // Realizamos la prueba con este producto
    // ...
  });
  
  it('debería calcular correctamente el total de múltiples productos', () => {
    // Productos con precios específicos para validar sumas
    const product1 = generateFakeProduct({ price: 10 });
    const product2 = generateFakeProduct({ price: 20 });
    
    // Prueba con estos productos
    // ...
    // Verificamos que el total sea 30
  });
});

Beneficios de sistematizar la creación de datos simulados

La implementación de un sistema de mocking bien estructurado ofrece múltiples ventajas:

  • Reducción de código repetitivo: Evitamos escribir la misma lógica de creación de datos en múltiples pruebas.
  • Mayor claridad en las pruebas: Las pruebas se centran en lo que realmente queremos probar, no en la configuración de datos.
  • Facilidad para crear escenarios complejos: Podemos generar rápidamente diferentes variaciones de datos.
  • Mejor mantenibilidad: Si cambia la estructura de nuestros modelos, solo necesitamos actualizar la función de generación.
  • Ayuda a la IA: Proporciona patrones claros que las herramientas de IA pueden entender y utilizar para generar más casos de prueba.

Cuando trabajamos con servicios más complejos que incluyen inyección de dependencias, el mocking se vuelve aún más importante, ya que nos permite simular el comportamiento de esas dependencias sin necesidad de instanciarlas realmente.

La sistematización de la creación de datos simulados es una inversión que mejora significativamente la calidad y mantenibilidad de nuestras pruebas. ¿Has implementado técnicas de mocking en tus proyectos? Comparte tu experiencia y las estrategias que has encontrado más efectivas.