【问题标题】:Unit Testing: should change class after click单元测试:点击后应该改变类
【发布时间】:2018-03-14 15:49:35
【问题描述】:

点击<mat-expansion-panel> (Angular Material) 时,它应该添加一个类mat-expanded,但每当我运行该函数时,当我记录它时,DOM 仍然是一样的,并没有添加该类。

HTML

<mat-expansion-panel (opened)="toggleCollapseRow('open')" (closed)="toggleCollapseRow('closed')">
...

component.ts 中的函数

public toggleCollapseRow(openOrClosed: string): void {
    if (openOrClosed === 'open') {
        this.expandCollapseIcon = 'ic_collapse_default';
    } else if (openOrClosed === 'closed') {
        this.expandCollapseIcon = 'ic_expand_default';
    }
}

单元测试

it('should expand on click', fakeAsync(() => {
    fixture.detectChanges();
    const panel = fixture.nativeElement.querySelector('mat-expansion-panel');
    const spy = spyOn(component, 'toggleCollapseRow').and.callThrough();
    panel.click();
    component.toggleCollapseRow('open');
    tick();
    fixture.detectChanges();
    // this logs the same output with no class added
    console.log(fixture.nativeElement.querySelector('mat-expansion-panel'));
    expect(spy);
    expect(component.toggleCollapseRow).toHaveBeenCalled();
    expect(component.expandCollapseIcon).toEqual('ic_collapse_default');
}));

这一切都成功了,但是当我添加以下内容时,它失败了,因为 DOM 仍然相同:

expect(fixture.nativeElement.querySelector('.mat-expanded')).toBeTruthy()

【问题讨论】:

    标签: angular unit-testing typescript karma-jasmine


    【解决方案1】:

    如果测试测试toggleCollapseRow 的工作原理,则不应涉及点击。如果它测试模板的工作方式,则不应直接调用component.toggleCollapseRow('open')。正因为如此,期望才成功。

    the guide 中所述,DOM 事件应使用DebugElement triggerEventHandler 触发,因为HTMLElement click 不涉及绑定。

    应该是这样的:

    const panelDE = fixture.debugElement.query(By.directive(MatExpansionPanel));
    const spy = spyOn(component, 'toggleCollapseRow').and.callThrough();
    panelDE.triggerEventHandler('click', null);
    tick();
    fixture.detectChanges();
    expect(component.toggleCollapseRow).toHaveBeenCalled();
    expect(component.expandCollapseIcon).toEqual('ic_collapse_default');
    expect(panelDE.classes['mat-expanded']).toBeTruthy()
    

    【讨论】:

    • By.directive(MatExpansionPanel) 是什么?我似乎没有为此导入。使用你的代码,不幸的是它仍然没有添加类
    • 如果你没有导入,它会合理地导致错误。当然,它不会添加类。您应该为此添加导入。如果可以的话,请使用 IDE 自动导入。 By 是 Angular 助手,angular.io/api/platform-browser/By。 MatExpansionPanel 是 Material 应该导出的组件类。
    • 对,它现在导入了 MatExpansionPanel。它仍然在所有测试中失败。图标不相等,函数没有被调用,最后一个是假的
    • 我希望它能够工作。考虑提供一种方法来复制实际问题 - Plunker、Stackblitz 等。此外,由于您不应该测试 Material 单元(这是 Angular 团队的工作),您还可以采用更直接的方法,例如 @987654331 @ 而不是 triggerEventHandler。另一种选择是提供虚拟&lt;mat-expansion-panel&gt; 组件而不是真实组件,以消除不需要的移动部件。
    猜你喜欢
    • 1970-01-01
    • 2023-04-10
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多