I am not sure why the the change event isn't firing and therefore not triggering the function I registered for the change event.
I know this works when I run it, but I can't get it in the spec.
Here is a demo of what I am talking about... As you can see from the logs, the toggle never gets called:
https://stackblitz.com/edit/angular-material-slide-toggle-test-utmbmy?file=app%2Fhello.component.spec.ts
Roughly, this is my code here...
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;
}
In my spec.ts:
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);
});
The after logging does print out slider.checked to be the opposite value from before. However, the component.useDefault stays the same and the logging statement in the toggle function is never called, which means it never triggered it.
Why is this going on and how do I fix this?
I've tried placing the whole thing into fakeAsync, using tick, placing the 'after' code into fixture.whenStable() and fixture.whenRenderingDone().
I have a NoopAnimationsModule in the TestBed's import.
When using third-party components, you should trust them to handle the event. However, you could trigger the event, using the triggereventhandler while you spyOn the method you want to be called.
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
});
See the test passing on stackblitz: https://stackblitz.com/edit/angular-material-slide-toggle-test-spy-trigger-event?file=app/hello.component.spec.ts
<mat-slide-toggle (change)="onToggle($event)">Compare</mat-slide-toggle>
event.checked = true || false;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With