Angular 测试:点击按钮时输出发射器 returns dispatchEvent 为 null

Angular Testing: Output emitter on button click returns null for dispatchEvent

我的 Angular 组件中的函数:

@Output() projectEvent = new EventEmitter<string>();

openProjectDashboard(projectKey: string) {
    this.projectEvent.emit(projectKey);
}

HTML:

<div class="project-container">
  <div
    class="project-card"
    *ngFor="let project of projects"
    (click)="openProjectDashboard(project.key)"
  </div>
  ....
</div>

我的测试:

beforeEach(() => {
    fixture = TestBed.createComponent(ProjectGridComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    
    spyOn(component.projectEvent, "emit");
    spyOn(component, "openProjectDashboard");
});

it("should emit event", () => {
    // component.openProjectDashboard("DE365");
    // expect(component.openProjectDashboard).toHaveBeenCalled();

    const nativeElement = fixture.nativeElement;
    const div = nativeElement.querySelector(".project-card");
    div.dispatchEvent(new Event('click'));

    fixture.detectChanges();
    expect(component.projectEvent.emit).toHaveBeenCalled();
});

我在 运行 测试时遇到错误:

Error: TypeError: Cannot read property 'dispatchEvent' of null

当您 spyOn 某些东西时,您会丢失实现细节。您必须调用 callThrough 才能保留旧的实现细节。

尝试:

beforeEach(() => {
    fixture = TestBed.createComponent(ProjectGridComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    
    spyOn(component.projectEvent, "emit");
    spyOn(component, "openProjectDashboard").and.callThrough(); // add callThrough here so the function actually runs
});

it("should emit event", () => {
    // component.openProjectDashboard("DE365");
    // expect(component.openProjectDashboard).toHaveBeenCalled();

    const nativeElement = fixture.nativeElement;
    const div = nativeElement.querySelector(".project-card");
    div.dispatchEvent(new Event('click'));

    fixture.detectChanges();
    expect(component.projectEvent.emit).toHaveBeenCalled();
});