Signalsと非同期コードのテスト
リアクティブな振る舞いと非同期の振る舞いをテストします
「Signalsと非同期コードのテスト」はCoddyKit上の無料Angular Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAngular Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Angular Academyコースには全4レッスンが含まれています。
非同期処理がテストの難所です
実際のコンポーネントは、タイマー、Promise、HTTP、デバウンスされた入力などの非同期処理を行います。テストでは、非同期処理が完了した後にアサーションが実行されるよう、時間を制御する必要があります。Angularには、時間を決定論的に制御するためのfakeAsync、tick、flushが用意されています。
シグナルをテストする
signalは関数のように読み取ります。テストは単純です。シグナルを呼び出して値を検証し、値を更新してもう一度検証します。
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シグナルは自動的に更新される
computedは依存関係が変わると再計算されます。テストでは元のシグナルを変更してから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でPromiseをテストする
Promiseはマイクロタスクとして解決されます。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は、読み取っているシグナルが変化した後に非同期で実行されます。その結果を確認するには、変更検知(またはflush)を実行してeffectを動かしてから、副作用を検証します。
c.theme.set('dark');
fixture.detectChanges(); // effect runs
expect(document.body.classList.contains('dark')).toBe(true);よくある落とし穴:タイマーの残留
fakeAsyncのテスト終了時にタイマーがキューに残っていると、Angularはエラーをスローします。必ずtick/flushで処理するか、ngOnDestroyでインターバルを解除し、テスト終了時に仮想時計を空にしてください。
クイックチェック
既知の遅延時間に適したツールを選んでください。
まとめ
シグナルは単純な関数と同じようにテストします(読み取りには呼び出し、更新にはset、DOMにはdetectChangesを使います)。非同期処理では、fakeAsyncが仮想時計を提供し、tickで進め、flushで処理を空にし、flushMicrotasksでPromiseを解決します。タイマーを保留したままにしないでください。
よくある質問
「Signalsと非同期コードのテスト」レッスンは無料ですか?
はい。「Signalsと非同期コードのテスト」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Angular Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Angular Academyコースには全4レッスンが含まれています。
「Signalsと非同期コードのテスト」で何を学びますか?
リアクティブな振る舞いと非同期の振る舞いをテストします ブラウザで直接実行するハンズオンコードでAngular Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Angular Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAngular Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「Signalsと非同期コードのテスト」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAngular Academyレッスンでコードを書いて実行できますか?
はい。すべてのAngular Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- TestBedとコンポーネントフィクスチャ
- Inputs、Outputs、DOMのテスト
- サービスと依存関係のモック
- Signalsと非同期コードのテスト