Jasmine предоставляет мощные инструменты для тестирования
асинхронного кода, где важную роль играет управление временем. Одним из
таких инструментов является функция tick, которая позволяет
симулировать прохождение времени в тестах, делая возможным проверку
таймеров, задержек и промисов без реального ожидания.
tickДля работы с tick необходимо включить fake
timers с помощью функции
jasmine.clock().install(). Это подменяет стандартные
таймеры JavaScript (setTimeout, setInterval)
на управляемые Jasmine версии, что позволяет контролировать время точно
и предсказуемо.
beforeEach(function() {
jasmine.clock().install();
});
afterEach(function() {
jasmine.clock().uninstall();
});
beforeEach и afterEach гарантируют, что
каждый тест начнется с чистой среды, а любые изменения таймеров не будут
влиять на другие тесты.
tickМетод tick принимает один аргумент — количество
миллисекунд, на которое необходимо “перемотать” время вперед. Все
таймеры, назначенные на этот интервал, будут выполнены синхронно.
it("выполняет таймер через 100 мс", function() {
const callback = jasmine.createSpy("callback");
setTimeout(callback, 100);
jasmine.clock().tick(100);
expect(callback).toHaveBeenCalled();
});
Ключевые моменты:
tick меньше, чем длительность таймера,
функция не сработает.tick(50); tick(50); эквивалентно
tick(100);.Для функций, использующих setInterval, tick
позволяет проверить многократные срабатывания интервала.
it("вызывает функцию несколько раз по интервалу", function() {
const callback = jasmine.createSpy("callback");
setInterval(callback, 200);
jasmine.clock().tick(600);
expect(callback.calls.count()).toBe(3);
});
Каждое срабатывание интервала учитывается, а количество вызовов можно
проверить через calls.count().
tickФункции, использующие промисы и setTimeout, можно
тестировать без реального ожидания. Важно понимать, что
tick перематывает только таймеры, а
промисы обрабатываются через микротаски. Для тестирования комбинаций
таймеров и промисов необходимо использовать
Promise.resolve() или async/await вместе с
tick.
it("тестирует промис с таймером", async function() {
let result = null;
setTimeout(() => {
result = "done";
}, 100);
jasmine.clock().tick(100);
await Promise.resolve(); // дождаться микротасков
expect(result).toBe("done");
});
setTimeout и setIntervaltick работает только с таймерами, созданными после
вызова jasmine.clock().install().clock.tick
добавляет указанное количество миллисекунд к внутреннему счетчику
Jasmine. Это позволяет моделировать сложные сценарии с последовательными
таймерами.jasmine.clock().uninstall() необходимо вызывать в
afterEach, иначе последующие тесты могут работать
некорректно.Пример 1. Таймер с задержкой и проверкой состояния:
it("изменяет состояние через 500 мс", function() {
let state = "initial";
setTimeout(() => {
state = "updated";
}, 500);
expect(state).toBe("initial");
jasmine.clock().tick(500);
expect(state).toBe("updated");
});
Пример 2. Последовательные интервалы:
it("интервал с увеличением счетчика", function() {
let counter = 0;
setInterval(() => { counter += 2; }, 100);
jasmine.clock().tick(300);
expect(counter).toBe(6);
});
Использование tick позволяет тестировать сложные
тайминговые сценарии полностью синхронно, исключая зависимость от
реального времени и ускоряя выполнение тестового набора.