Mocking de Servicios Externos con NodeMailer en Pruebas Tuen

Clase 23 de 25Curso de End to End Testing para APIs REST con Node.js

Resumen

¿Qué es el mocking y por qué es importante en las pruebas?

El uso de mocking se convierte en una herramienta esencial al realizar pruebas de aplicaciones complejas, especialmente cuando se trabajan con servicios externos que escapan a nuestro control. En el testing de software, el mocking permite simular el comportamiento de ciertos componentes o servicios para verificar cómo la aplicación responde a diversas condiciones sin depender de servicios externos reales.

¿Por qué necesitamos hacer mocking?

Durante la ejecución de pruebas end-to-end, tratamos de integrar la mayor cantidad de componentes posibles de nuestra aplicación, incluyendo bases de datos y servicios externos. Sin embargo, llega un punto en el que no es factible o posible asegurar toda la funcionalidad de estos servicios de terceros, como es el caso de APIs externas o servicios de correo electrónico.

Razones para usar mocking:

  • Control limitado: APIs externas o servicios como NodeMailer para el envío de correos electrónicos no están bajo nuestro control directo, lo que complica la validación de su correcta ejecución.
  • Consumo de recursos: Llamar frecuentemente a servicios de terceros, como tecnología de procesamiento de imágenes de Microsoft, puede aumentar costos innecesarios si se usan sin restricciones.
  • Pruebas intencionadas: Utilizar datos falsos para simular condiciones específicas y verificar la respuesta de la aplicación, sin involucrar servicios reales que podrían causar un mal uso.

¿Cómo funciona el mocking con NodeMailer?

Un caso práctico de mocking se da al trabajar con la función NodeMailer, la cual gestiona el envío de correos electrónicos, como se describió en el ejemplo de recuperación de contraseñas. Al enviar un correo para recuperar una contraseña, no se puede verificar si el correo llegó con éxito, ya que no tenemos acceso a la base de datos de servicios como Gmail. Por lo tanto, emulamos mediante mocking que el correo ha sido enviado.

Implementación del mocking:

  1. Definición del EndPoint: La aplicación recibe un email para verificar si el usuario existe y firma un JWT que se guardará en la base de datos para el proceso de recuperación de contraseña.

  2. Envío de Email: Aquí reside el mayor desafío, ya que no podemos confirmar la entrega del correo en Gmail. Simularemos esta acción asegurando que supuestamente se ha enviado con éxito.

Código de Mocking:

// Definimos la funcionalidad de mocking en Jest
const mockSendMail = jest.fn();
jest.mock('nodemailer', () => {
  return {
    createTransport: jest.fn().mockImplementation(() => {
      return {
        sendMail: mockSendMail
      };
    })
  };
});

// Simulamos el comportamiento esperado
mockSendMail.mockResolvedValue(true);

¿Qué hacer si las pruebas fallan?

Al ejecutar pruebas, hemos de asegurarnos que las funciones simuladas estén siendo llamadas correctamente. En caso de errores, como en las credenciales de SMTP, es crucial que las pruebas no se detengan, ya que están diseñadas para ser independientes del correo electrónico real.

Uso de console.log para depuración

El console.log sigue siendo una herramienta valiosa cuando necesitamos comprender la salida de nuestras pruebas, especialmente para identificar dónde se están produciendo los errores. Esto ayuda no solo a encontrar errores en mi código, sino también en mi lógica de pruebas:

console.log(body); // Ayuda a depurar

¿Qué sigue después de implementar el mocking?

Una vez que hemos asegurado que nuestras pruebas funcionan eficientemente mediante mocking, podemos avanzar hacia la automatización de pruebas en plataformas como GitHub Actions. Esto nos permitirá ejecutar nuestras pruebas con cada cambio en el código de manera eficiente, garantizando siempre la calidad y estabilidad de nuestra aplicación.