使用Promise包装器的setTimeout无法与Jest async / await配合使用

时间:2019-04-13 18:26:49

标签: javascript jestjs

试图用玩笑做一个相对简单的断言。我有以下测试设置:

const sleep = ms => new Promise(res => setTimeout(res, ms));

it('should call callback after specified delay', async () => {
  const mockCallback = jest.fn();

  setTimeout(1000, mockCallback);

  expect(mockCallback).not.toHaveBeenCalled();

  await sleep(1000);

  expect(mockCallback).toHaveBeenCalled();
});

运行时,测试失败并显示以下错误:

Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.

很明显,这远没有达到这个阈值。知道我在做什么错吗?

[更新] 我意识到以前我在考试前曾打电话给jest.useFakeTimers()。删除并重新运行测试后,我仍然失败,但这不是超时。而是简单地

Expected mock function to have been called, but it was not called.

请注意,当睡眠时间显着增加到4000ms时,也是这种情况。

相反,如果我从setTimeout切换到

sleep(ONE_SECOND)
  .then(mockCallback);

测试通过。笑话清楚地修改了setTimeout与Promises并行交互的方式,但是发生了什么并不明显。

1 个答案:

答案 0 :(得分:0)

您只需要将mockCallback作为第一个参数传递给setTimeout

const sleep = ms => new Promise(res => setTimeout(res, ms));

it('should call callback after specified delay', async () => {
  const mockCallback = jest.fn();

  setTimeout(mockCallback, 1000);  // <= pass mockCallback as first argument

  expect(mockCallback).not.toHaveBeenCalled();  // Success!

  await sleep(1000);

  expect(mockCallback).toHaveBeenCalled();  // Success!
});