Angular 单元测试点击方法似乎没有被点击

Angular unit test click method isn't appearing to be clicked

这看起来应该很简单,但我无法验证是否在我的组件上调用了点击处理程序。

header.component.ts

import { Component, EventEmitter, OnInit, Output } from '@angular/core';

@Component({
    selector: 'app-header',
    templateUrl: './header.component.html',
    styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
    @Output() hamburgerToggle = new EventEmitter<void>();

    constructor() {}

    ngOnInit(): void {}

    hamburgerClicked(): void {
        this.hamburgerToggle.emit();
    }
}

header.component.html

<nav class="sb-topnav navbar navbar-expand navbar-dark bg-dark">
    <div class="hamburger header-toggle">
        <button (click)="hamburgerClicked()" class="btn btn-link btn-sm order-first order-first header-toggle" id="sidebarToggle" href="/">
            <i class="material-icons header-toggle">menu</i>
        </button>
    </div>
</nav>

header.component.spec.ts

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { HeaderComponent } from './header.component';

describe('HeaderComponent', () => {
    let component: HeaderComponent;
    let fixture: ComponentFixture<HeaderComponent>;

    beforeEach(async () => {
        await TestBed.configureTestingModule({
            declarations: [HeaderComponent]
        }).compileComponents();
    });

    beforeEach(() => {
        fixture = TestBed.createComponent(HeaderComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('clicking the toggle button invoke our click handler', () => {
        const fixture = TestBed.createComponent(HeaderComponent);

        const clickSpy = spyOn(component, 'hamburgerClicked');
        const toggleButton = fixture.debugElement.query(By.css('#sidebarToggle'));
        toggleButton.triggerEventHandler('click', toggleButton);

        fixture.detectChanges();

        expect(clickSpy).toHaveBeenCalledTimes(1);
    });
});

给出的错误信息是:

Expected spy hamburgerClicked to have been called once. It was called 0 times.

我也在异步块中尝试过这个,但收到了相同的结果:

fit('clicking the toggle button invoke our click handler', fakeAsync(() => {
    const fixture = TestBed.createComponent(HeaderComponent);

    const clickSpy = spyOn(component, 'hamburgerClicked');
    const toggleButton = fixture.nativeElement.querySelector('#sidebarToggle');
    toggleButton.click();

    tick();
    fixture.detectChanges();

    fixture.whenStable().then(() => {
        expect(clickSpy).toHaveBeenCalledTimes(1);
    });
}));

我已经在这里工作了几个小时,但无法弄清楚我错过了什么。非常感谢任何帮助。

您在每个测试用例中创建一个新的 fixture(组件实例)。但是您监视了在 beforeEach 中创建的组件。因此,您在每个新组件实例上触发点击事件,它们不是同一个组件。

您应该添加一个间谍,查询 DOM 元素,并在同一组件实例上触发点击事件。

在每个测试用例中删除以下语句将起作用:

const fixture = TestBed.createComponent(HeaderComponent);

header.component.ts:

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { HeaderComponent } from './header.component';

fdescribe('HeaderComponent', () => {
  let component: HeaderComponent;
  let fixture: ComponentFixture<HeaderComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [HeaderComponent],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(HeaderComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('clicking the toggle button invoke our click handler', () => {
    const clickSpy = spyOn(component, 'hamburgerClicked');
    const toggleButton = fixture.debugElement.query(By.css('#sidebarToggle'));
    toggleButton.triggerEventHandler('click', toggleButton);
    expect(clickSpy).toHaveBeenCalledTimes(1);
  });

  it('clicking the toggle button invoke our click handler', () => {
    const clickSpy = spyOn(component, 'hamburgerClicked');
    const toggleButton = fixture.nativeElement.querySelector('#sidebarToggle');
    toggleButton.click();
    expect(clickSpy).toHaveBeenCalledTimes(1);
  });
});

单元测试结果:

Chrome 80.0.3987.87 (Mac OS 10.13.6): Executed 2 of 17 (skipped 15) SUCCESS (0.1 secs / 0.045 secs)
TOTAL: 2 SUCCESS
✔ Browser application bundle generation complete.
✔ Browser application bundle generation complete.