Как проверить обещание рекурсии с JEST - PullRequest
2 голосов
/ 14 мая 2019

Я пишу тест, используя JEST. Я не знаю, как проверить рекурсию обещаний в JEST.

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

export function retry <T> (fn: () => Promise <T>, limit: number = 5, interval: number = 10): Promise <T> {
  return new Promise ((resolve, reject) => {
    fn ()
      .then (resolve)
      .catch ((error) => {
        setTimeout (async () => {
          // Reject if the upper limit number of retries is exceeded
          if (limit === 1) {
            reject (error);
            return;
          }
          // If it is less than the upper limit number of retries, execute callback processing recursively
          await retry (fn, limit-1, interval);
        }, interval);
      });
  });
}

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

  1. Всегда передавайте обещание для разрешения, и функция повтора разрешается при первом выполнении
  2. Передайте разрешение для разрешения при третьем запуске, а функция повтора разрешается при третьем запуске

Я думал, что при написании этих слов в JEST будет следующее.

describe ('retry', () => {
  test ('resolve on the first call', async () => {
    const fn = jest.fn (). mockResolvedValue ('resolve!');
    await retry (fn);
    expect (fn.mock.calls.length) .toBe (1);
  });

  test ('resolve on the third call', async () => {
    const fn = jest.fn ()
               .mockRejectedValueOnce (new Error ('Async error'))
               .mockRejectedValueOnce (new Error ('Async error'))
               .mockResolvedValue ('OK');
    expect (fn.mock.calls.length) .toBe (3)
  });
});

В результате произошла ошибка при следующей ошибке.

Timeout-Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error:
    > 40 | test ('resolve on the third call', async () => {
         | ^
      41 | const fn = jest
      42 | .fn ()
      43 | .mockRejectedValueOnce (new Error ('Async error'))

Я думаю, что это будет возможным при настройке JEST в отношении этой ошибки. Однако, в принципе, я не знаю, как проверить рекурсивную обработку обещаний в JEST.

Ответы [ 2 ]

2 голосов
/ 14 мая 2019

Может быть, ваша retry задача займет слишком много раз (например: 4,9s), тогда у вас не будет достаточно времени, чтобы выполнить следующий тестовый пример.

Вы можете увеличить timeout JEST с помощьюjest.setTimeout(10000);

Обещание тестирования официальный документ.

Мое решение для вашего случая:

test("resolve on the third call", async () => {
    jest.setTimeout(10000);
    const fn = jest.fn()
      .mockRejectedValueOnce(new Error("Async error"))
      .mockRejectedValueOnce(new Error("Async error"))
      .mockResolvedValue("OK");

    // test reject value
    await expect(fn()).rejects.toEqual(new Error("Async error"));
    await expect(fn()).rejects.toEqual(new Error("Async error"));

    // test resolve
    const result = await fn();
    expect(result).toEqual("OK");

    // call time
    expect(fn).toHaveBeenCalledTimes(3);
  });
1 голос
/ 14 мая 2019

Тайм-аут происходит потому, что обработчик .catch() в retry() не вызывает resolve, когда он делает вторую попытку вызова retry();поэтому первый retry() возвращает обещание, которое никогда не разрешается и не отклоняется.

Замена await на resolve() может помочь (и функция в setTimeout не должна быть асинхронной):

  .catch ((error) => {
    setTimeout (() => {
      // Reject if the upper limit number of retries is exceeded
      if (limit === 1) {
        reject (error);
        return;
      }
      // If it is less than the upper limit number of retries, execute callback processing recursively
      resolve(retry (fn, limit-1, interval));
    }, interval);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...