lundi 19 octobre 2020

Angular testing why is flush necessary when clicking but not in triggerEventHandler

I have an Angular module with a list, card, detail, and edit components.

The list template would look like this:

<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>

When testing that when clicking the card it goes to its detail page:

  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}`);
  }));

works fine.

When testing that when clicking the create button goes to edit:

  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`);
  }));

it fails with 1 periodic timer(s) still in the queue.

If I add flush as such:

  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`);
  }));

it works well.

And if I switch to 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`);
  }));

then it works, without the flush.

Could someone explain why it works or doesn't in each situation?

Aucun commentaire:

Enregistrer un commentaire