单元测试失败:如何正确 select 并单击组件按钮
Unit test failing: How do I properly select and click a components button
我这里有一个单元测试:
fit('should call getImageByID upon submit when a search id is present', () => {
spyOn(component, 'getImageById');
component.searchId = '1';
submit = fixture.debugElement.query(By.css('#getimagebyid')).nativeElement;
submit.click();
expect(component.getImageById).toHaveBeenCalled();
});
单元测试失败,因为没有满足预期(方法没有被执行),我错过了什么?这是未被触发的组件方法:
getImageById() {
this.imageAPIService.getImage(this.searchId).subscribe(res => {
this.response.id = (res as any).id;
this.response.image = (res as any).image;
});
}
和组件的 html:
<h4>Browse Images</h4>
<div class="row">
<img *ngIf="response.id != null" [src]="response.image[0].url" height="200">
</div>
<div class="row">
<input [(ngModel)]="searchId" type="text">
<button class="btn btn-block btn-primary" id="getimagebyid" [disabled]="!searchId" (click)="getImageById(searchId)">Search</button>
</div>
大功告成,但需要等待点击事件处理完毕,再检查方法是否被调用。
1) 最直接的方法是调用 detectChanges() 显式激活变化检测。
it('clicking on settings icon will trigger openModal method', () => {
spyOn(component, 'getImageById');
component.searchId = '1';
submit = fixture.debugElement.query(By.css('#getimagebyid')).nativeElement;
submit.click();
fixture.detectChanges();
expect(component.getImageById).toHaveBeenCalled();
});
2) 或者,您可以在 .spec 文件中使用 automatic change detection。
import { ComponentFixtureAutoDetect, . . . . } from '@angular/core/testing';
.
.
TestBed.configureTestingModule({
declarations: [ BannerComponent ],
providers: [
{ provide: ComponentFixtureAutoDetect, useValue: true }
]
});
3) 使用async()功能处理异步按钮点击事件。随后调用 .whenStable()
,即 returns 承诺。
import { async, . . . . } from '@angular/core/testing';
.
.
it('clicking on settings icon will trigger openModal method', async(() => {
spyOn(component, 'getImageById');
component.searchId = '1';
submit = fixture.debugElement.query(By.css('#getimagebyid')).nativeElement;
submit.click();
fixture.whenStable().then(() => {
expect(component.getImageById).toHaveBeenCalled();
});
}));
我能想到的最简单的解决方案是:
it('should call getImageByID upon submit when a search id is present', () => {
const spy = spyOn(component, 'getImageById');
fixture.debugElement.query(By.css('#getimagebyid'))
.triggerEventHandler('click', null);
expect(spy).toHaveBeenCalledTimes(1);
});
我这里有一个单元测试:
fit('should call getImageByID upon submit when a search id is present', () => {
spyOn(component, 'getImageById');
component.searchId = '1';
submit = fixture.debugElement.query(By.css('#getimagebyid')).nativeElement;
submit.click();
expect(component.getImageById).toHaveBeenCalled();
});
单元测试失败,因为没有满足预期(方法没有被执行),我错过了什么?这是未被触发的组件方法:
getImageById() {
this.imageAPIService.getImage(this.searchId).subscribe(res => {
this.response.id = (res as any).id;
this.response.image = (res as any).image;
});
}
和组件的 html:
<h4>Browse Images</h4>
<div class="row">
<img *ngIf="response.id != null" [src]="response.image[0].url" height="200">
</div>
<div class="row">
<input [(ngModel)]="searchId" type="text">
<button class="btn btn-block btn-primary" id="getimagebyid" [disabled]="!searchId" (click)="getImageById(searchId)">Search</button>
</div>
大功告成,但需要等待点击事件处理完毕,再检查方法是否被调用。
1) 最直接的方法是调用 detectChanges() 显式激活变化检测。
it('clicking on settings icon will trigger openModal method', () => {
spyOn(component, 'getImageById');
component.searchId = '1';
submit = fixture.debugElement.query(By.css('#getimagebyid')).nativeElement;
submit.click();
fixture.detectChanges();
expect(component.getImageById).toHaveBeenCalled();
});
2) 或者,您可以在 .spec 文件中使用 automatic change detection。
import { ComponentFixtureAutoDetect, . . . . } from '@angular/core/testing';
.
.
TestBed.configureTestingModule({
declarations: [ BannerComponent ],
providers: [
{ provide: ComponentFixtureAutoDetect, useValue: true }
]
});
3) 使用async()功能处理异步按钮点击事件。随后调用 .whenStable()
,即 returns 承诺。
import { async, . . . . } from '@angular/core/testing';
.
.
it('clicking on settings icon will trigger openModal method', async(() => {
spyOn(component, 'getImageById');
component.searchId = '1';
submit = fixture.debugElement.query(By.css('#getimagebyid')).nativeElement;
submit.click();
fixture.whenStable().then(() => {
expect(component.getImageById).toHaveBeenCalled();
});
}));
我能想到的最简单的解决方案是:
it('should call getImageByID upon submit when a search id is present', () => {
const spy = spyOn(component, 'getImageById');
fixture.debugElement.query(By.css('#getimagebyid'))
.triggerEventHandler('click', null);
expect(spy).toHaveBeenCalledTimes(1);
});