测试一个函数,它有承诺和目,它为什么时间了?

0

的问题

我想测试一个函数 setTimeout 内部一个承诺。 然而,它保持时序。

这是功能:

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

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

这是我的测试:

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 };

  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("sleep end");
});

问题是,当我尝试运行这个测试失败,并给出了这样的信息:

thrown: "Exceeded timeout of 5000 ms for a test.
    Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."

我已经试过了 jest.setTimeout(10000) 这只会引发错误的 Exceeded timeout of 10000ms ...

任何主意,为什么本事? 或如何解决这个问题?

谢谢!

javascript jestjs settimeout timeout
2021-11-24 01:41:50
1

最好的答案

1

这里有一个解决方案,更接近什么你要去的。 重要的是,你不能 await 该决议的承诺使用的假定时器或者它永远不会解决。 相反,你可以打电话分配的返回值 sleep 功能以一个可变的,随后运行的计时器,然后等着的变量。

我也调整你的 expect 声明超时间谍因为它需要两个参数。 最后,我删除了你的expectationt, sleep 被称为与持续时间,因为你是从字面上这样做,在试验,因此它似乎不值得作出这一说法。

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 };

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

  const sleepFn = sleep(+SLEEP_DURATION);

  jest.runAllTimers();

  // Now that we ran timers we can await the promise resolving 
  await sleepFn;

  // timeout takes two arguments
  expect(timeoutSpy).toHaveBeenCalledWith(
    expect.any(Function),
    +SLEEP_DURATION
  );
  expect(console.log).toHaveBeenCalledWith("sleep end");
});
2021-11-24 02:03:50

感谢您的内容翔实的答案,这是我第一次使用这些开玩笑计时器,所以我肯定有一些研究以这样做!
ffx292

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................