Je ne sais pas pourquoi l'événement de changement ne se déclenche pas et ne déclenche donc pas la fonction que j'ai enregistrée pour l'événement de changement.
Je sais que cela fonctionne lorsque je l'exécute, mais je ne peux pas l'obtenir dans les spécifications.
Voici une démonstration de ce dont je parle ... Comme vous pouvez le voir dans les journaux, le toggle
n'est jamais appelé: https://stackblitz.com/edit/angular-material- slide-toggle-test-utmbmy? file = app% 2Fhello.component.spec.ts
En gros, voici mon code ici ...
component.html:
<mat-slide-toggle [checked]="useDefault" (change)="toggle($event)"></mat-slide-toggle>
component.ts:
...
toggle(event: MatSlideToggleChange) {
console.log('Toggle fired');
this.useDefault = event.checked;
}
Dans mes spécifications:
it('should trigger toggle...', () => {
const componentDebug = fixture.debugElement;
const slider: MatSlideToggle =
componentDebug.query(By.css('form mat-slide-toggle')).componentInstance;
console.log('before ' + slider.checked);
slider.toggle();
fixture.detectChanges();
console.log('after ' + slider.checked);
console.log('useDefault ' + component.useDefault);
});
La journalisation after
imprime slider.checked
Pour être la valeur opposée de before
. Cependant, component.useDefault
Reste le même et l'instruction de journalisation dans la fonction toggle
n'est jamais appelée, ce qui signifie qu'elle ne l'a jamais déclenchée.
Pourquoi cela se passe-t-il et comment résoudre ce problème?
J'ai essayé de placer le tout dans fakeAsync
, en utilisant tick
, en plaçant le code 'after' dans fixture.whenStable()
et fixture.whenRenderingDone()
.
J'ai un NoopAnimationsModule
dans le TestBed
de import
.
Lorsque vous utilisez des composants tiers, vous devez leur faire confiance pour gérer l'événement. Cependant, vous pouvez déclencher l'événement en utilisant triggereventhandler tandis que vous spyOn la méthode que vous souhaitez appeler.
import { Component } from '@angular/core';
import { MatSlideToggleChange } from '@angular/material';
@Component({
selector: 'hello',
template: `
<mat-slide-toggle
[checked]="useDefault" (change)="toggle($event)"
></mat-slide-toggle>`
})
export class HelloComponent {
public useDefault = false;
public toggle(event: MatSlideToggleChange) {
console.log('toggle', event.checked);
this.useDefault = event.checked;
}
}
it('should call change method on slide change', () => {
const componentDebug = fixture.debugElement;
const slider = componentDebug.query(By.directive(MatSlideToggle));
spyOn(component, 'toggle'); // set your spy
slider.triggerEventHandler('change', null); // triggerEventHandler
expect(component.toggle).toHaveBeenCalled(); // event has been called
});
Voir le test passant sur stackblitz: https://stackblitz.com/edit/angular-material-slide-toggle-test-spy-trigger-event?file=app/hello.component.spec.ts =