Тестирование сигналов и асинхронного кода
Тестируйте реактивное и асинхронное поведение
«Тестирование сигналов и асинхронного кода» — бесплатный урок Angular Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Angular Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Angular Academy содержит 4 уроков всего.
Асинхронность — самая сложная часть тестирования
Реальные компоненты выполняют асинхронную работу: используют таймеры, промисы, HTTP и ввод с задержкой. Тесты должны управлять временем, чтобы проверки выполнялись после завершения асинхронной работы. Angular предоставляет fakeAsync, tick и flush для детерминированного управления временем.
Тестирование сигнала
Сигнал считывается как функция. Тестировать его просто: вызовите сигнал и проверьте значение, затем обновите его и проверьте значение снова.
it('increments the count signal', () => {
const fixture = TestBed.createComponent(CounterComponent);
const c = fixture.componentInstance;
expect(c.count()).toBe(0);
c.increment();
expect(c.count()).toBe(1);
});Вычисляемые сигналы обновляются автоматически
computed пересчитывается при изменении зависимостей. В тесте измените исходный сигнал, а затем считайте вычисляемый — вручную пересчитывать его не требуется.
expect(c.doubled()).toBe(0);
c.count.set(5);
expect(c.doubled()).toBe(10); // computed(() => c.count() * 2)Сигналы и DOM
Чтобы увидеть изменение сигнала в шаблоне, вызовите detectChanges() после его обновления, как и при изменении любого другого состояния.
c.count.set(3);
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toContain('3');Знакомство с fakeAsync
Оберните тест в fakeAsync, чтобы перейти в виртуальную временную зону. Таймеры и микрозадачи ставятся в очередь, а не выполняются сразу, поэтому Вы перемещаете время вручную. Благодаря этому асинхронные тесты становятся синхронными и надежными.
import { fakeAsync, tick } from '@angular/core/testing';
it('loads after delay', fakeAsync(() => {
// timers are now under your control
}));Перемещение времени с помощью tick
tick(ms) перемещает виртуальные часы вперед и запускает все таймеры, запланированные в этом интервале.
it('fires after 1s', fakeAsync(() => {
let done = false;
setTimeout(() => (done = true), 1000);
expect(done).toBe(false);
tick(1000);
expect(done).toBe(true);
}));flush для всех ожидающих таймеров
Если точная задержка неизвестна, flush() выполняет все ожидающие макрозадачи, пока очередь не опустеет.
import { fakeAsync, flush } from '@angular/core/testing';
it('completes debounced search', fakeAsync(() => {
component.search('ang');
flush(); // run all timers (e.g. debounceTime)
expect(component.results().length).toBeGreaterThan(0);
}));Тестирование промисов с помощью fakeAsync
Промисы выполняются как микрозадачи. Внутри fakeAsync вызовите flushMicrotasks() (или tick()), чтобы завершить их выполнение перед проверкой.
import { fakeAsync, flushMicrotasks } from '@angular/core/testing';
it('resolves promise', fakeAsync(() => {
let v: number | undefined;
Promise.resolve(42).then((n) => (v = n));
flushMicrotasks();
expect(v).toBe(42);
}));Вспомогательная функция async / waitForAsync
Для тестов, которым нужно дождаться реальной асинхронной работы без управления временем, оберните тело в waitForAsync и используйте fixture.whenStable().
import { waitForAsync } from '@angular/core/testing';
it('settles', waitForAsync(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(fixture.componentInstance.ready()).toBe(true);
});
}));Тестирование effect()
effect выполняется асинхронно после изменения сигналов, которые он считывает. Чтобы увидеть результат, запустите обнаружение изменений (или выполните очистку), чтобы эффект выполнился, а затем проверьте побочный эффект.
c.theme.set('dark');
fixture.detectChanges(); // effect runs
expect(document.body.classList.contains('dark')).toBe(true);Распространенная проблема: оставшиеся таймеры
Если тест fakeAsync завершается, пока в очереди остаются таймеры, Angular выдает ошибку. Всегда выполняйте их с помощью tick/flush или очищайте интервалы в ngOnDestroy, чтобы при завершении теста виртуальные часы были пусты.
Быстрая проверка
Выберите подходящий инструмент для известной задержки.
Итоги
Сигналы тестируются как простые функции: вызов считывает значение, set обновляет его, а detectChanges обновляет DOM. Для асинхронной работы fakeAsync предоставляет виртуальные часы: перемещайте их с помощью tick, очищайте очередь с помощью flush, а промисы завершайте с помощью flushMicrotasks. Никогда не оставляйте таймеры ожидающими.
Часто задаваемые вопросы
Урок «Тестирование сигналов и асинхронного кода» бесплатный?
Да — полный текст урока «Тестирование сигналов и асинхронного кода» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Angular Academy, подпишись на CoddyKit PRO. Курс Angular Academy содержит 4 уроков всего.
Чему я научусь в уроке «Тестирование сигналов и асинхронного кода»?
Тестируйте реактивное и асинхронное поведение Ты практикуешь Angular Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Angular Academy?
Предыдущий опыт не требуется. Angular Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Тестирование сигналов и асинхронного кода»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Angular Academy?
Да. Каждый урок Angular Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- TestBed и приспособления компонентов
- Тестирование входных данных, выходных данных и DOM
- Имитация сервисов и зависимостей
- Тестирование сигналов и асинхронного кода