Der Autor arbeitet seit drei Jahren am SAP China Research Institute an der Frontend-Entwicklung des Produkts SAP Commerce Cloud (E-Commerce Cloud). Die E-Commerce-Cloud Storefront basiert auf dem Open-Source-Projekt Spartacus und die Adresse des Github-Code-Warehouses kann über diesen Link aufgerufen werden .
Das Team, in dem ich derzeit arbeite, war für die Entwicklung der serverseitigen Rendering-Logik (SSR) von Spartacus verantwortlich, einschließlich der Entwicklung der Rendering-Engine (Rendering Engine) und des unterstützenden Unit-Test-Codes. Während des Entwicklungsprozesses musste eine Menge Code getestet werden, der die Verwendung von @angular/core/testing
fakeAsync in diesem Entwicklungspaket erforderte, um den Unit-Test abzuschließen. Daher nutzte ich auch die Gelegenheit bei der Arbeit, um eingehende Untersuchungen zur Verwendung von durchzuführen fakeAsync.
Wie der Name schon sagt fakeAsync
, dient dieses Tool der Simulation asynchroner Vorgänge und der Abwicklung zeitbezogener Aufgaben. @angular/core/testing
Wie Sie anhand des Entwicklungspakets, in dem es sich befindet, erkennen können, besteht der Zweck dieses Tools darin, Angular-Entwicklern das Schreiben und Ausführen von Testfällen zu erleichtern.
fakeAsync
Ermöglicht uns, Testcode im synchronen Stil zu schreiben und gleichzeitig asynchrone Vorgänge zu simulieren, ohne tatsächlich auf den Abschluss der asynchronen Aufgabe warten zu müssen. Dies ist beim Unit-Testen von Angular-Anwendungen sehr wertvoll, da wir häufig Komponenten oder Dienste im Zusammenhang mit asynchronen Vorgängen testen müssen.
Was ist fakeAsync
?
fakeAsync
Es ist Teil des Angular-Testframeworks und bietet eine Möglichkeit, asynchrone Vorgänge zu simulieren, sodass Testfälle synchron geschrieben werden können. Normalerweise verwenden wir in Angular-Anwendungen asynchrone Vorgänge, um diese async
abzuwickeln await
. Beim Testen kann dies jedoch dazu führen, dass der Code des Testfalls komplex und schwer verständlich wird. Das Ziel der Einführung fakeAsync
besteht darin, den Testcode zu vereinfachen und ihn leichter lesbar und wartungsfreundlich zu machen.
fakeAsync
Zu den Hauptfunktionen gehören:
-
Timer simulieren : Entwickler können Timerfunktionen usw.
fakeAsync
simulierensetTimeout
, sodass die Wartezeit in Tests nicht zu tatsächlichem Warten führt.setInterval
-
Zeitsteuerung :
fakeAsync
Die Möglichkeit, die Zeit explizit vorzuverlegen, um den Abschluss eines asynchronen Vorgangs zu simulieren, anstatt darauf zu warten, dass die tatsächliche Zeit vergeht. -
Synchroner Testcode : Sie können
fakeAsync
synchronen Code innerhalb eines Blocks schreiben, ohne asynchrone Vorgänge zu verwendenasync
undawait
zu verarbeiten.
Wie benutzt man fakeAsync
?
Um es zu verwenden fakeAsync
, müssen Sie es zunächst importieren und den Testcodeblock umschließen. Konventionell verwenden wir in unseren Testsuiten Codeblöcke, describe
um den Testcode fakeAsync
in Funktionen zu packen. Anschließend können Sie tick
die Funktion verwenden, um die Zeit voranzutreiben und den Abschluss eines asynchronen Vorgangs zu simulieren.
Hier sind fakeAsync
die allgemeinen Schritte zur Verwendung:
- Importieren
fakeAsync
:
import {
fakeAsync } from '@angular/core/testing';
- Verwenden Sie in der Testsuite
fakeAsync
:
describe('MyComponent', () => {
it('should do something asynchronously', fakeAsync(() => {
// 测试代码
}));
});
tick
Zum Vorrücken der Zeit verwenden :
it('should do something asynchronously', fakeAsync(() => {
// 模拟异步操作
setTimeout(() => {
// 这里可以编写异步操作完成后要执行的代码
}, 1000);
// 推进时间,模拟异步操作完成
tick(1000);
}));
#Beispiel: fakeAsync
Komponententest mit
Lassen Sie uns ein Beispiel durchgehen, um zu demonstrieren, wie es beim Testen von Angular-Komponenten verwendet wird fakeAsync
. Nehmen wir an, wir haben eine einfache Komponente CounterComponent
, die eine Schaltfläche und einen Zähler enthält, der sich jedes Mal um 1 erhöht, wenn auf die Schaltfläche geklickt wird. Wir werden einen Testfall schreiben, um sicherzustellen, dass sich der Zähler korrekt verhält.
Erstellen Sie zunächst CounterComponent
:
// counter.component.ts
import {
Component } from '@angular/core';
@Component({
selector: 'app-counter',
template: `
<button (click)="increment()">Increment</button>
<p>{
{ count }}</p>
`,
})
export class CounterComponent {
count = 0;
increment() {
this.count++;
}
}
Schreiben Sie als Nächstes einen Testfall, um das Verhalten von zu fakeAsync
testen :CounterComponent
// counter.component.spec.ts
import {
ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import {
CounterComponent } from './counter.component';
describe('CounterComponent', () => {
let fixture: ComponentFixture<CounterComponent>;
let component: CounterComponent;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [CounterComponent],
});
fixture = TestBed.createComponent(CounterComponent);
component = fixture.componentInstance;
});
it('should increment count when the button is clicked', fakeAsync(() => {
// 触发按钮点击事件
const button = fixture.nativeElement.querySelector('button');
button.click();
// 推进时间,模拟异步操作完成
tick();
// 断言计数器的值是否增加
expect(component.count).toBe(1);
// 再次触发按钮点击事件
button.click();
// 推进时间,模拟异步操作完成
tick();
// 断言计数器的值是否进一步增加
expect(component.count).toBe(2);
}));
});
Im obigen Testfall haben wir zunächst das Klickereignis der Schaltfläche simuliert und dann tick
die Zeit verlängert, um den Abschluss des asynchronen Vorgangs zu simulieren. Als nächstes stellen wir fest, ob der Zählerwert wie erwartet steigt.
Mit fakeAsync
können wir asynchrone Vorgänge als synchron behandeln, was das Schreiben und Verstehen von Testfällen erleichtert.
Analoger Timer
fakeAsync
Kann auch zum Emulieren von Timerfunktionen wie setTimeout
und verwendet werden setInterval
.
Auch anhand von Beispielen veranschaulicht.
Nehmen wir an, wir haben eine Komponente TimerComponent
, die nach der Initialisierung 5 Sekunden wartet und dann eine Meldung anzeigt. Wir werden einen Testfall schreiben, um sicherzustellen, dass die Nachricht nach 5 Sekunden korrekt angezeigt wird.
Erstellen Sie zunächst TimerComponent
:
// timer.component.ts
import {
Component, OnInit } from '@angular/core';
@Component({
selector: 'app-timer',
template: `
<p *ngIf="showMessage">{
{ message }}</p>
`,
})
export class TimerComponent implements OnInit {
showMessage = false;
message = 'Message after 5 seconds';
ngOnInit() {
setTimeout(() => {
this.showMessage = true;
}, 5000);
}
}
Schreiben Sie als Nächstes Testfälle mit fakeAsync
und, um das Verhalten von tick
zu testen :TimerComponent
// timer.component.spec.ts
import {
ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import {
TimerComponent } from './timer.component';
describe('TimerComponent', () => {
let fixture: ComponentFixture<TimerComponent>;
let component: TimerComponent;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TimerComponent],
});
fixture = TestBed.createComponent(TimerComponent);
component = fixture.componentInstance;
});
it('should display the message after 5 seconds', fakeAsync(() => {
// 触发组件的 ngOnInit,模拟定时器启动
fixture.detectChanges();
// 断言消息未显示
expect(component.showMessage).toBe(false);
// 推进时间,模拟等待5秒钟
tick(5000);
// 断言消息已显示
expect(component.showMessage).toBe(true);
// 获取消息元素并断言消息文本
const messageElement = fixture.nativeElement.querySelector('p');
expect(messageElement.textContent).toBe('Message after 5 seconds');
}));
});
Im obigen Testfall lösen wir zuerst die Komponente aus ngOnInit
und tick
simulieren dann mit der Push-Zeit eine Wartezeit von 5 Sekunden. Abschließend prüfen wir, ob die Meldung nach 5 Sekunden korrekt angezeigt wird.
Zusammenfassen
fakeAsync
Es handelt sich um ein leistungsstarkes Tool im Angular-Testframework, das das Schreiben und Ausführen asynchroner Testfälle vereinfacht. Es ermöglicht Entwicklern, asynchrone Vorgänge als synchron zu behandeln, Timerfunktionen zu simulieren und den Zeitfortschritt beim Schreiben von Unit-Tests zu steuern, wodurch Tests einfacher zu schreiben und zu verstehen sind.