javascript - 带有 Promise 包装器的 setTimeout 无法按预期使用 Jest async/await

标签 javascript jestjs

尝试用 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.

请注意,当 sleep 时间显着增加到 4000 毫秒时也是如此。

如果我从 setTimeout 切换到

sleep(ONE_SECOND)
  .then(mockCallback);

测试通过。 Jest 清楚地修改了 setTimeout 如何与 Promises 并行交互,但不清楚发生了什么。

最佳答案

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

关于javascript - 带有 Promise 包装器的 setTimeout 无法按预期使用 Jest async/await,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55668630/

相关文章:

javascript - 无法获得 while 循环工作(崩溃页面)

node.js - 开 Jest - 有没有办法检查测试覆盖率的百分比?

unit-testing - 在 Jest 测试覆盖率报告中显示 'E'

unit-testing - 使用 jest 和 vue-test-utils2 在 vue3 typescript 单元测试中模拟 axios (已解决)

vue.js - 测试 VueX 商店

javascript - 构建我的第一个 Javascript 应用程序 (jQuery),苦苦挣扎

javascript - 使用 Chart.js 堆叠条形图中的空白

javascript - jQuery 获取父项

javascript - 设置 css 背景在 firefox 中不起作用

javascript - 我如何用 Jest 来模拟异步提取?