Jasmine поддерживает асинхронное тестирование, включая работу с промисами. Важной особенностью является возможность возврата промиса из функции теста, что позволяет фреймворку корректно ожидать завершения асинхронной операции перед проверкой утверждений.
Когда функция теста возвращает промис, Jasmine автоматически ожидает
его разрешения или отклонения. Это устраняет необходимость вручную
вызывать done() и упрощает написание асинхронных
проверок.
Пример базового теста с промисом:
it('должен получить данные с сервера', function() {
return fetchData().then(function(data) {
expect(data).toBeDefined();
expect(data.length).toBeGreaterThan(0);
});
});
В этом примере:
fetchData() возвращает промис.С введением async/await синтаксис становится более
читаемым, сохраняя возможность возврата промиса:
it('должен корректно обработать асинхронный запрос', async function() {
const data = await fetchData();
expect(data).toBeDefined();
expect(data.length).toBeGreaterThan(0);
});
Важно отметить:
await позволяет писать асинхронный код линейно, без
цепочек .then().Если промис отклоняется, Jasmine автоматически фиксирует ошибку
теста. Можно дополнительно проверять отлов исключений с помощью
expectAsync:
it('должен выбросить ошибку при некорректных данных', async function() {
await expectAsync(fetchData('invalid')).toBeRejected();
});
Ключевые методы expectAsync:
toBeResolved(): промис успешно разрешился.toBeRejected(): промис отклонён.toBeResolvedTo(value): промис разрешился с конкретным
значением.toBeRejectedWith(error): промис отклонён с конкретной
ошибкой.Асинхронные операции часто выполняются в хуках
beforeEach и afterEach. Для работы с промисами
они также могут возвращать промис:
beforeEach(function() {
return initializeDatabase();
});
afterEach(function() {
return cleanupDatabase();
});
Или с async/await:
beforeEach(async function() {
await initializeDatabase();
});
afterEach(async function() {
await cleanupDatabase();
});
Это гарантирует, что все тесты будут выполняться только после завершения подготовительных и завершающих операций.
done и возврат промиса.
Либо использовать done, либо возвращать промис/async
функцию, иначе поведение теста может быть непредсказуемым.it('неправильный пример', function() {
fetchData().then(function(data) {
expect(data).toBeDefined();
});
});
В этом случае Jasmine завершит тест до завершения промиса, что приведет к ложноположительным результатам.
Правильный вариант — вернуть промис:
it('правильный пример', function() {
return fetchData().then(function(data) {
expect(data).toBeDefined();
});
});
Promise.all или
for...of с await, чтобы Jasmine корректно
дождался всех операций.Когда промисы зависят от таймеров (setTimeout), Jasmine
предоставляет возможность управления временем через
jasmine.clock(). В сочетании с возвратом промиса это
позволяет синхронно тестировать асинхронное поведение:
it('должен дождаться таймера', function() {
jasmine.clock().install();
const promise = new Promise(resolve => setTimeout(() => resolve('done'), 1000));
jasmine.clock().tick(1000);
return promise.then(result => {
expect(result).toBe('done');
}).finally(() => jasmine.clock().uninstall());
});
expectAsync для проверки
отклонённых промисов.beforeEach, afterEach).done и промисов.Возврат промиса из тестов является стандартным и безопасным способом работы с асинхронным кодом в Jasmine, обеспечивая точное ожидание результата и правильное управление ошибками.