es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué se produce un tiempo de espera al probar una función que tiene una Promesa y setTimeout?

Estoy intentando probar una función que tiene setTimeout dentro de una promesa. Sin embargo, sigue agotando el tiempo de espera.

Esta es la función:

export const sleep = async (duration: number): Promise<void> => {
  await new Promise<void>((resolve) => {
    setTimeout(resolve, duration);
  });

  if (process.env.NODE_ENV === "test") {
    console.log("fin del sleep");
  }
};

Y este es mi test:

import { sleep } from "../../helpers/utils";

console.log = jest.fn();
jest.useFakeTimers();

test("llama a la función sleep con el argumento correcto y llama a console.log", async () => {
  const NODE_ENV = "test";
  const SLEEP_DURATION = "100";

  process.env = { ...process.env, NODE_ENV, SLEEP_DURATION };

  const timeoutSpy = jest.spyOn(global, "setTimeout");

  await sleep(+SLEEP_DURATION);

  jest.runAllTimers();

  expect(sleep).toHaveBeenCalledWith(+SLEEP_DURATION);
  expect(timeoutSpy).toHaveBeenCalledWith(+SLEEP_DURATION);
  expect(console.log).toHaveBeenCalledWith("fin del sleep");
});

El problema es que cuando trato de correr esto, el test falla y da este mensaje:

Lanzado: "Excedido el tiempo de espera de 5000 ms para una prueba. 
    Use jest.setTimeout (nuevo tiempo de espera) para aumentar el valor del tiempo de espera si se trata de una prueba de larga duración. "

He intentado jest.setTimeout(10000), lo que solo produce un error de Excedido el tiempo de espera de 10000 ms...

¿Alguna idea de por qué está sucediendo esto? ¿O cómo solucionarlo?

¡Gracias!

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que el setTimeout en tu función sleep está causando que tu prueba expire. Jest tiene un tiempo límite predeterminado de 5000ms para las pruebas, y como tu función espera una duración especificada (en este caso, 100ms), es posible que la prueba esté tardando demasiado en completarse y, por lo tanto, expire.

    Una solución para esto sería simular la función setTimeout en tu prueba y hacer que se ejecute inmediatamente en lugar de esperar la duración especificada. Puedes hacer esto usando jest.useFakeTimers() al principio de tu archivo de prueba, y luego llamando a jest.runAllTimers() después de llamar a tu función sleep.

    Aquí tienes una versión actualizada de tu prueba con estos cambios:

    import { sleep } from "../../helpers/utils";
    
    console.log = jest.fn();
    
    jest.useFakeTimers();
    
    test("calls sleep with correct argument and calls console.log", async () => {
      const NODE_ENV = "test";
      const SLEEP_DURATION = "100";
    
      process.env = { ...process.env, NODE_ENV, SLEEP_DURATION };
    
      await sleep(+SLEEP_DURATION);
    
      jest.runAllTimers();
    
      expect(sleep).toHaveBeenCalledWith(+SLEEP_DURATION);
      expect(console.log).toHaveBeenCalledWith("sleep end");
    });
    

    Nota que ya no necesitamos espiar la función setTimeout ya que estamos usando jest.useFakeTimers(). Además, hemos eliminado la instrucción expect para el espía timeoutSpy, ya que ya no es necesaria.

Comments are closed.