简体   繁体   English

带有 Promise 包装器的 setTimeout 与 Jest async/await 无法按预期工作

[英]setTimeout with Promise wrapper not working as expected with Jest async/await

Trying to do a relatively simple assertion with jest.试图用玩笑做一个相对简单的断言。 I have the following test setup:我有以下测试设置:

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

When I run the test fails with the following error:当我运行测试失败并出现以下错误时:

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

Obviously this is nowhere near that threshold.显然,这远不及该阈值。 Any idea what I'm doing wrong?知道我做错了什么吗?

[UPDATE] I realized previously I had called jest.useFakeTimers() before the test. [更新] 我之前意识到我在测试前调用了jest.useFakeTimers() After removing this and running the test again I still get a failure but it's not a timeout.删除它并再次运行测试后,我仍然失败,但这不是超时。 Instead just simply而是简单地

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

Note this is also the case when significantly increasing the sleep to 4000ms.请注意,将睡眠时间显着增加到 4000 毫秒时也是如此。

If instead I switch from setTimeout to如果相反,我从 setTimeout 切换到

sleep(ONE_SECOND)
  .then(mockCallback);

the test passes.测试通过。 Jest clearly modifies how setTimeout interacts in parallel with Promises, but it's not obvious as to what is going on. Jest 清楚地修改了 setTimeout 与 Promises 并行交互的方式,但不清楚发生了什么。

You just need to pass mockCallback as the first argument to setTimeout :您只需要将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!
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM