setTimeout с оболочкой Promise не работает должным образом с Jest async / await - PullRequest
1 голос
/ 13 апреля 2019

Попытка сделать относительно простое утверждение с шуткой. У меня есть следующие настройки теста:

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, но не очевидно, что происходит.

1 Ответ

0 голосов
/ 14 апреля 2019

Вам просто нужно передать 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!
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...