В Jasmine tick используется вместе с функциями симуляции
времени, такими как jasmine.clock(), для контроля
асинхронных операций, основанных на таймерах (setTimeout,
setInterval). Механизм позволяет тестам работать
детерминированно, исключая реальные задержки и ускоряя выполнение
тестов. Основное отличие tick с конкретным временем от
простого tick() заключается в возможности симулировать
прохождение точного интервала времени, что критично для проверки сложной
логики с несколькими таймерами или последовательными задержками.
Перед использованием tick необходимо активировать
подмену системного времени:
beforeEach(function() {
jasmine.clock().install();
});
afterEach(function() {
jasmine.clock().uninstall();
});
jasmine.clock().install() заменяет встроенные функции
setTimeout, setInterval,
clearTimeout и clearInterval собственными
моками, позволяя контролировать их поведение. uninstall()
возвращает исходное состояние системы.
Метод jasmine.clock().tick(milliseconds) принимает число
миллисекунд и симулирует их прохождение. Это позволяет “прокрутить”
таймеры вперед без реальной задержки:
it("вызывает колбек через 1000 мс", function() {
const callback = jasmine.createSpy("callback");
setTimeout(callback, 1000);
jasmine.clock().tick(500);
expect(callback).not.toHaveBeenCalled();
jasmine.clock().tick(500);
expect(callback).toHaveBeenCalled();
});
Ключевой момент: tick симулирует именно
прошедшее время, а не количество вызовов таймера. Если таймер установлен
на 1000 мс, вызов tick(500) не приводит к его
срабатыванию.
Когда в тесте несколько таймеров с разными интервалами,
tick позволяет точно контролировать их
последовательность:
it("правильно срабатывают несколько таймеров", function() {
const first = jasmine.createSpy("first");
const second = jasmine.createSpy("second");
setTimeout(first, 300);
setTimeout(second, 700);
jasmine.clock().tick(300);
expect(first).toHaveBeenCalled();
expect(second).not.toHaveBeenCalled();
jasmine.clock().tick(400);
expect(second).toHaveBeenCalled();
});
Здесь важно, что суммарное время tick учитывается
относительно установки таймеров, а не отдельно. Первый вызов
tick(300) двигает “часы” на 300 мс, второй
tick(400) — ещё на 400 мс, что в сумме даёт 700 мс.
setIntervalМетод tick применим и к интервалам. Таймер срабатывает
столько раз, сколько должно было пройти за указанный интервал
времени:
it("setInterval с tick", function() {
const callback = jasmine.createSpy("callback");
setInterval(callback, 200);
jasmine.clock().tick(200);
expect(callback.calls.count()).toBe(1);
jasmine.clock().tick(400);
expect(callback.calls.count()).toBe(3);
});
Особенность: интервал срабатывает каждый раз, когда
“время движется” на шаг больше или равный его интервалу, даже если
tick вызывается сразу на несколько интервалов.
jasmine.clock().tick() не влияет на промисы или другие
микротаски, основанные на Event Loop. Для работы с ними необходимо
использовать async/await или done() вместе с
реальными таймерами.clock() в
beforeEach/afterEach, иначе мокирование может
повлиять на соседние тесты.tick всегда суммирует
прошедшее время, поэтому последовательные вызовы учитывают предыдущие
шаги.it("комбинация setTimeout и setInterval", function() {
const single = jasmine.createSpy("single");
const repeat = jasmine.createSpy("repeat");
setTimeout(single, 500);
setInterval(repeat, 300);
jasmine.clock().tick(300);
expect(single).not.toHaveBeenCalled();
expect(repeat.calls.count()).toBe(1);
jasmine.clock().tick(200);
expect(single).toHaveBeenCalled();
expect(repeat.calls.count()).toBe(1);
jasmine.clock().tick(300);
expect(repeat.calls.count()).toBe(2);
});
В этом примере tick позволяет синхронизировать
срабатывания разных таймеров без реальных задержек, проверяя как
одиночные таймауты, так и повторяющиеся интервалы.
tick,
чтобы тесты были предсказуемыми.tick() без аргумента — это может
привести к неконтролируемым срабатываниям.tick на последовательные шаги, чтобы точно отслеживать
состояние.Использование jasmine.clock().tick() с точным временем
обеспечивает детерминированность тестов, ускоряет выполнение и упрощает
проверку сложной логики, зависящей от асинхронных таймеров.