Тестирование асинхронного кода
Зачастую JavaScript код выполняется асинхронно. При работе с асинхронным кодом, Jest нужно знать когда тестируемый код завершен, до того, как он сможет перейти к следующему тесту. В Jest этого можно добиться несколькими способами.
Промисы
Возвращайте промис в своем тесте, и Jest будет ждать resolve
— успешного завершения промиса. Если промис отклонён(reject), то утверждение не будет выполнено.
Например, представьте что fetchData
вместо использования коллбэка возвращает промис, который должен в случае успешного выполнения вернуть строку 'peanut butter'
. Мы можем протестировать это поведение так:
test('the data is peanut butter', () => {
return fetchData().then(data => {
expect(data).toBe('peanut butter');
});
});
Async/Await
Кроме того, Вы можете использовать async
и await
в Ваших тестах. Чтобы написать асинхронный тест, просто используйте async
перед определением функции передаваемой в test
. Например, тот же fetchData
сценарий может быть протестирован следующим образом:
test('the data is peanut butter', async () => {
const data = await fetchData();
expect(data).toBe('peanut butter');
});
test('the fetch fails with an error', async () => {
expect.assertions(1);
try {
await fetchData();
} catch (error) {
expect(error).toMatch('error');
}
});
Вы можете комбинировать async
и await
вместе с .resolves
или .rejects
.
test('данные являются арахисовым маслом', async () => {
await expect(fetchData()).resolves.toBe('арахисовое масло');
});
test('fetch вернёт ошибку', async () => {
await expect(fetchData()).rejects.toMatch('error');
});
В этих случаях, async
и await
удобный синтаксический сахар для той же самой логики, что использовалась с примерами на промисах.
Убедитесь, что вы возвращаете промис или ожидаете его завершения. Если вы пропустите выражение return
/await
, ваш тест будет завершён до того, как промис, полученный от fetchData
разрешит(resolve) или отклонит(reject) его.
Если Вы ожидаете, что промис будет отклонён, используйте метод .catch
. Убедитесь, что добавлены expect.assertions
, чтобы убедиться, что вызвано определенное количество утверждений. В противном случае, завершённый промис не провалит тест.
test('the fetch fails with an error', () => {
expect.assertions(1);
return fetchData().catch(error => expect(error).toMatch('error'));
});
Обратные вызовы
Если вы не используете промисы, вы можете использовать обратные вызовы. Например, предположим, что fetchData
вместо возврата промиса ожидает коллбек, т.е. извлекает некоторые данные и вызывает callback(null, data)
по завершении. И вы хотите проверить, что возвращаемые данные это строка 'арахисовое масло'
.
По умолчанию Jest тесты завершаются, как только они достигают конца их исполнения. Это значит, что этот тест не будет работать как предполагается:
// Не делайте так!
test('the data is peanut butter', () => {
function callback(error, data) {
if (error) {
throw error;
}
expect(data).toBe('peanut butter');
}
fetchData(callback);
});