Angular 2+:带有mat-slide-toggle的测试表单-更改事件不会触发

use*_*183 5 angular-material angular

我不确定更改事件为何未触发,因此不触发我为更改事件注册的功能。

我知道我在运行它时可以运行,但是我无法在规范中找到它。

这是我正在谈论的演示...从日志中可以看到,toggle永远不会被调用:https : //stackblitz.com/edit/angular-material-slide-toggle-test-utmbmy?file= app%2Fhello.component.spec.ts

大概,这是我的代码在这里...

component.html:

<mat-slide-toggle [checked]="useDefault" (change)="toggle($event)"></mat-slide-toggle>
Run Code Online (Sandbox Code Playgroud)

component.ts:

...
toggle(event: MatSlideToggleChange) {
  console.log('Toggle fired');
  this.useDefault = event.checked;
}
Run Code Online (Sandbox Code Playgroud)

在我看来:

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);
});
Run Code Online (Sandbox Code Playgroud)

after记录不会打印出slider.checked是从相反的值before。但是,component.useDefault保持不变,并且toggle永远不会调用该函数中的logging语句,这意味着它永远不会触发它。

为什么会这样,我该如何解决?

我尝试将整个内容放入fakeAsync和使用tick,然后将“之后”代码放入fixture.whenStable()fixture.whenRenderingDone()

我有一个NoopAnimationsModuleTestBedimport

小智 10

你的 component.html

    <mat-slide-toggle (change)="onToggle($event)">Compare</mat-slide-toggle>
Run Code Online (Sandbox Code Playgroud)

在您的组件中,您可以检查

    event.checked = true || false;
Run Code Online (Sandbox Code Playgroud)


Leo*_*iro 7

使用第三方组件时,应信任它们来处理事件。但是,您可以在spyOn要调用的方法时使用triggereventhandler触发事件。

零件

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

测试

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
});
Run Code Online (Sandbox Code Playgroud)

请参阅通过stackblitz的测试:https ://stackblitz.com/edit/angular-material-slide-toggle-test-spy-trigger-event ? file = app/hello.component.spec.ts