angular / angular/components

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

Ouverte
#20,785 5 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
area: cdk/testing P3
Langage dominant
TypeScript
Étoiles
25k
Forks
6.8k
Merge moyen
1 j 8 h
PR mergées (30 j)
91

Description

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.

Guide de contribution

Ouvrir le guide de contribution

Piste de recherche

Commencez par la reproduction StackBlitz et le point d’entrée TestbedHarnessEnvironment, en vous concentrant sur son utilisation de ComponentFixture#whenStable. Comparez le comportement avec les guides Angular et Zone liés concernant fakeAsync, tick et discardPeriodicTasks. Le travail est terminé lorsque le cas de l’intervalle dispose d’un comportement pris en charge convenu, soit un parcours fonctionnel du harness, soit une documentation expliquant la limitation et le modèle de test compatible.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
angular, typescript
Domaine
testing
Type d'issue
Bug
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.