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.
这看起来应该很简单,但我无法验证是否在我的组件上调用了点击处理程序。
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.