Как я могу проверить задержки обещания с шуткой? - PullRequest
0 голосов
/ 06 октября 2018

Вот мой код, который я использую для отсрочки процесса (для отката)

export function promiseDelay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

Я бы хотел проверить его, но не смог.Я пытался работать с fakeTimers, но мой тест никогда не заканчивается.

test('promiseDelay delays for 1s', async (done) => {
    jest.useFakeTimers();
    Promise.resolve().then(() => jest.advanceTimersByTime(100));
    await promiseDelay(100);
  });

Ответы [ 2 ]

0 голосов
/ 07 октября 2018

promiseDelay возвращает Promise, которое разрешается после ms, поэтому вызовите spy in then и проверьте, был ли spy вызван через различные интервалы:

describe('promiseDelay', () => {

  beforeEach(() => { jest.useFakeTimers(); });
  afterEach(() => { jest.useRealTimers(); });

  test('should not resolve until timeout has elapsed', async () => {
    const spy = jest.fn();
    promiseDelay(100).then(spy);  // <= resolve after 100ms

    jest.advanceTimersByTime(20);  // <= advance less than 100ms
    await Promise.resolve();  // let any pending callbacks in PromiseJobs run
    expect(spy).not.toHaveBeenCalled();  // SUCCESS

    jest.advanceTimersByTime(80);  // <= advance the rest of the time
    await Promise.resolve();  // let any pending callbacks in PromiseJobs run
    expect(spy).toHaveBeenCalled();  // SUCCESS
  });

});

Обратите внимание, что тестовый код является синхронным и Mock Timer делает setTimeout синхронным, но then ставит в очередь обратный вызов в PromiseJobs, поэтому любые обратные вызовы в очереди должны быть разрешены допроверка, был ли вызван spy.

Это можно сделать с помощью функции теста async и вызова await для разрешенного Promise, который фактически ставит в очередь оставшуюся часть теста в концеиз PromiseJobs разрешить запуск любых ожидающих обратных вызовов до продолжения теста.

Дополнительная информация о том, как взаимодействуют обещания и фальшивые таймеры, доступна в моем ответе здесь .

0 голосов
/ 06 октября 2018

Я думаю, вам просто нужно вернуть обещание из функции, например

test('promiseDelay delays for 1s',() => {
  jest.useFakeTimers();
  return Promise.resolve().then(() => jest.advanceTimersByTime(100));
});

, а затем шпионить setTimeout для вызова один раз.

...