【问题标题】:setTimeout with Promise wrapper not working as expected with Jest async/await带有 Promise 包装器的 setTimeout 在 Jest async/await 中无法按预期工作
【发布时间】:2019-09-04 05:20:21
【问题描述】:

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

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.

请注意,将睡眠时间显着增加到 4000 毫秒时也会出现这种情况。

如果我从 setTimeout 切换到

sleep(ONE_SECOND)
  .then(mockCallback);

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

【问题讨论】:

  • 您可能应该将sleep 比您希望被调用的setTimeout 长一点
  • 我无法重现该问题。也许您正在使用早于承诺支持的 Jest 版本,您应该升级它?
  • 已尝试设置更长的睡眠时间(最多 4000 毫秒)但没有成功。开玩笑的版本是 24.4.0,我相信它支持 async/await。我在其他地方用酶成功地使用了 async/await
  • 从未使用过 Jest,但它似乎希望您使用提供的回调作为函数的参数(该参数通常称为 done)。因此,您必须将async () 替换为async (done),并在应该完成测试时使用done()。但我不知道为什么会在这里期待这个(我使用过类似的测试框架,但在这里我有点困惑)。也许它与setTimeout 挂钩,如果使用它,它会确定这是一个异步测试,需要使用done() 完成?
  • 无论如何,如果睡眠时间太短,断言应该会失败,所以我认为这与问题无关。

标签: javascript jestjs


【解决方案1】:

您只需将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!
});

【讨论】:

  • ...但是是的,Promises 和计时器一起测试可能会很棘手,更多详细信息 available here
猜你喜欢
  • 2019-12-04
  • 2021-03-11
  • 1970-01-01
  • 2020-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多