Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як тестувати асинхронний код і Promise, щоб тест не проходив хибно?

Головна небезпека в асинхронних тестах - тест завершується раніше, ніж перевірка. Тест, у якому жодна перевірка не виконалася, вважається пройденим.

Неправильно:

it('завантажує користувача', () => {
  fetchUser(1).then((user) => {
    expect(user.name).toBe('Олена');   // виконається після завершення тесту
  });
});

Тест «зелений» навіть тоді, коли fetchUser повертає зовсім іншого користувача.

Правильно - async/await:

it('завантажує користувача', async () => {
  const user = await fetchUser(1);

  expect(user.name).toBe('Олена');
});

Тестовий фреймворк чекає на Promise, який повертає функція тесту.

Перевірка відхиленого Promise:

it('кидає помилку для неіснуючого користувача', async () => {
  await expect(fetchUser(999)).rejects.toThrow('Not found');
});

it('повертає дані', async () => {
  await expect(fetchUser(1)).resolves.toMatchObject({ id: 1 });
});

await перед expect(...).rejects обов'язковий - без нього перевірка знову не встигне виконатися.

Варіант з try/catch потребує захисту:

it('кидає помилку', async () => {
  expect.assertions(1);   // тест упаде, якщо перевірок буде не рівно одна

  try {
    await fetchUser(999);
  } catch (error) {
    expect(error.message).toBe('Not found');
  }
});

Без expect.assertions(1) тест пройде, якщо fetchUser помилково не кине винятку - блок catch просто не виконається.

Таймери й затримки не варто чекати по-справжньому (await new Promise(r => setTimeout(r, 3000))): тест стане повільним і нестабільним. Для цього є фейкові таймери.

Перевірка, що все дочекалося:

  • expect.hasAssertions() - хоча б одна перевірка виконалася;
  • vi.waitFor(() => expect(...)) - повторює перевірку, доки вона не пройде чи не мине час, коли результат з'являється не одразу.

Порада: напишіть тест, переконайтеся, що він падає, якщо зламати код. Тест, який ніколи не падав, міг нічого не перевіряти.

Докладніше в документації: Vitest: API expect

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання