angular / angular/components

bug(TestbedHarnessEnvironment): Impossible to use if component under test uses intervals

Aperta
#20,785 5 commenti 0 reazioni 0 assegnatari Vedi su GitHub
area: cdk/testing P3
Lingua principale
TypeScript
Stelle
25k
Fork
6.8k
Merge medio
1g 8h
PR unite (30g)
91

Descrizione

Use StackBlitz to reproduce your issue: **ADDED** (thanks @annieyw!), [example here](https://stackblitz.com/edit/material-testbedharness-interval?file=src/app/button-harness-example.spec.ts)

Steps to reproduce:
1. Follow [the instructions for using Harnesses](https://material.angular.io/guide/using-component-harnesses)
2. In the component under test, use `setInterval`, or the rxjs `interval(n)` or `timer(0, n)` observables
3. Your test will stall indefinitely at e.g. `await loader.getAllHarnesses(MatButtonHarness);` (from the docs linked in step 1)

#### Expected Behavior

`getAllHarnesses` completes once the component has finished initializing and had a chance to create instances of child components.

#### Actual Behavior

The call to `getAllHarnesses` never resolves, and the test times out.

#### Environment

- Angular: 10.1.2
- CDK/Material: 10.2.1
- Browser(s): N/A
- Operating System (e.g. Windows, macOS, Ubuntu): N/A (Win10)

----

As I understand it, this is because under the hood, `TestbedHarnessEnvironment` is using `ComponentFixture#whenStable`. From what I can tell, [the official stance from Angular / Zone](https://github.com/angular/angular/issues/10127) is that you should use `fakeAsync` plus `tick`, and call `discardPeriodicTasks` to ignore the (expected) pending intervals, instead of using `waitForAsync` / `whenStable`.

This [very old StackOverflow question](https://stackoverflow.com/questions/38697656/testing-angular2-components-that-use-setinterval-or-settimeout) suggests that one should never have `setInterval` in a component or service, instead using an injected service to provide periodic actions, so it can be mocked out during testing, but I've never seen anything "official" from Angular to say that intervals are unsupported.

If it's not permissible to use intervals in a component, this should be documented somewhere, with suggestions of alternative design patterns to use that are compatible with Material's test utilities. If it is permissible, `TestbedHarnessEnvironment` should be updated to include another way of determining when the owning `ComponentFixture` is "ready", or I guess kick this upstream to the Zone folks so they can make `whenStable` work with intervals.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia con la riproduzione StackBlitz e l’entry point TestbedHarnessEnvironment, concentrandoti sul suo utilizzo di ComponentFixture#whenStable. Confronta il comportamento con le guide Angular e Zone collegate relative a fakeAsync, tick e discardPeriodicTasks. Il lavoro è completato quando per il caso dell’intervallo è stato concordato un comportamento supportato, ossia un percorso funzionante dell’harness oppure una documentazione che spieghi la limitazione e il pattern di test compatibile.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
angular, typescript
Ambito
testing
Tipo di issue
Bug
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.