Angular 测试为什么在单击时需要刷新但在 triggerEventHandler 中不需要
Angular testing why is flush necessary when clicking but not in triggerEventHandler
我有一个 Angular 模块,其中包含列表、卡片、详细信息和编辑组件。
列表模板如下所示:
<own-list>
<button [routerLink]="['/', 'mod', 'create']" data-testid="new-request">Create</button>
<own-card *ngFor="let elem of elements" [routerLink]="['/', 'mod', elem.id]"></own-card>
<own-list>
测试单击卡片时它会转到其详细信息页面:
test('it should navigate to detail when clicking a card', fakeAsync(() => {
const cardElems = rootFixture.debugElement.queryAll(By.css('own-card'));
// Navigate to top card detail
cardElems[0].nativeElement.click();
tick();
fixture.detectChanges();
// Check route is correct
expect(location.path()).toBe(`/mod/${sortedElements[0].id}`);
}));
工作正常。
测试点击创建按钮进入编辑时:
test('it should navigate to edit when clicking new request', fakeAsync(() => {
const debugCreateBtn = rootFixture.debugElement.query(By.css(`[data-testid="new-request"]`));
// Navigate to edit
debugCreateBtn.nativeElement.click();
tick();
fixture.detectChanges();
// Check route is correct
expect(location.path()).toBe(`/mod/create`);
}));
失败 1 periodic timer(s) still in the queue
。
如果我这样添加 flush
:
test('it should navigate to edit when clicking new request', fakeAsync(() => {
const debugCreateBtn = rootFixture.debugElement.query(By.css(`[data-testid="new-request"]`));
// Navigate to edit
debugCreateBtn.nativeElement.click();
tick();
fixture.detectChanges();
flush(); // <-- new flush
// Check route is correct
expect(location.path()).toBe(`/mod/create`);
}));
效果不错。
如果我切换到 triggerEventHandler
:
test('it should navigate to edit when clicking new request', fakeAsync(() => {
const debugCreateBtn = rootFixture.debugElement.query(By.css(`[data-testid="new-request"]`));
// Navigate to edit
// Run in ngZone to avoid warning
fixture.ngZone.run(() => debugCreateBtn.triggerEventHandler('click', { button: 0 }));
tick();
fixture.detectChanges();
// Check route is correct
expect(location.path()).toBe(`/mod/create`);
}));
然后就可以了,没有冲洗。
有人可以解释为什么它在每种情况下都有效或无效吗?
flushMicrotasks 刷新挂起的微任务,tick 刷新挂起的微任务和进度时间,flush 刷新挂起的微任务、宏任务和进度时间,所有这些都在 fakeAsync 的上下文中。
像点击这样的原生事件是宏任务。未将异步设置为 true 的 triggerEventHandler 和 EventEmitter 使用微任务。
我有一个 Angular 模块,其中包含列表、卡片、详细信息和编辑组件。
列表模板如下所示:
<own-list>
<button [routerLink]="['/', 'mod', 'create']" data-testid="new-request">Create</button>
<own-card *ngFor="let elem of elements" [routerLink]="['/', 'mod', elem.id]"></own-card>
<own-list>
测试单击卡片时它会转到其详细信息页面:
test('it should navigate to detail when clicking a card', fakeAsync(() => {
const cardElems = rootFixture.debugElement.queryAll(By.css('own-card'));
// Navigate to top card detail
cardElems[0].nativeElement.click();
tick();
fixture.detectChanges();
// Check route is correct
expect(location.path()).toBe(`/mod/${sortedElements[0].id}`);
}));
工作正常。
测试点击创建按钮进入编辑时:
test('it should navigate to edit when clicking new request', fakeAsync(() => {
const debugCreateBtn = rootFixture.debugElement.query(By.css(`[data-testid="new-request"]`));
// Navigate to edit
debugCreateBtn.nativeElement.click();
tick();
fixture.detectChanges();
// Check route is correct
expect(location.path()).toBe(`/mod/create`);
}));
失败 1 periodic timer(s) still in the queue
。
如果我这样添加 flush
:
test('it should navigate to edit when clicking new request', fakeAsync(() => {
const debugCreateBtn = rootFixture.debugElement.query(By.css(`[data-testid="new-request"]`));
// Navigate to edit
debugCreateBtn.nativeElement.click();
tick();
fixture.detectChanges();
flush(); // <-- new flush
// Check route is correct
expect(location.path()).toBe(`/mod/create`);
}));
效果不错。
如果我切换到 triggerEventHandler
:
test('it should navigate to edit when clicking new request', fakeAsync(() => {
const debugCreateBtn = rootFixture.debugElement.query(By.css(`[data-testid="new-request"]`));
// Navigate to edit
// Run in ngZone to avoid warning
fixture.ngZone.run(() => debugCreateBtn.triggerEventHandler('click', { button: 0 }));
tick();
fixture.detectChanges();
// Check route is correct
expect(location.path()).toBe(`/mod/create`);
}));
然后就可以了,没有冲洗。
有人可以解释为什么它在每种情况下都有效或无效吗?
flushMicrotasks 刷新挂起的微任务,tick 刷新挂起的微任务和进度时间,flush 刷新挂起的微任务、宏任务和进度时间,所有这些都在 fakeAsync 的上下文中。
像点击这样的原生事件是宏任务。未将异步设置为 true 的 triggerEventHandler 和 EventEmitter 使用微任务。