我在一个旧页面中有一个搜索组件,我正试图为它写一些测试,但它给了我一些悲伤的
这是模板
<mat-form-field class="flex-row">
<mat-icon matPrefix>search</mat-icon>
<input #searchInput matInput placeholder="Search" type="text" [value]="search">
<button mat-icon-button matSuffix (click)="clear()" *ngIf="searchInput.value">
<mat-icon>
close
</mat-icon>
</button>
</mat-form-field>
组件使用MatInput
作为@ViewChild
export class SearchComponent implements OnInit, OnDestroy {
searchUpdate: Subject<string> = new Subject();
@ViewChild(MatInput, { static: true }) public searchInput: MatInput;
(...)
clear(): void {
this.searchInput.value = '';
this.searchUpdate.next(this.searchInput.value);
}
}
我正在尝试测试clear()
功能:
it('should clear search', fakeAsync(() => {
component.searchInput.value = 'test';
spyOn(component.searchChanged, 'emit');
component.clear();
expect(component.searchChanged.emit).toHaveBeenCalledWith('');
}));
但是我得到错误
TypeError:无法设置未定义的属性"value">
如果在运行测试时检查component.searchInput
的值,则为undefined
为什么输入变量在此测试的组件范围内不可用?或者,有什么更好的解决方案来测试这一点?
解决方案是将@Viewchild装饰器的查询更改为使用输入元素的模板id(#searchInput
(:
@ViewChild('searchInput', { static: true }) public searchInput: MatInput;
不太确定为什么其他查询不起作用,但这解决了我的问题,所以我把答案留给社区
试试这个:
it('should clear search', fakeAsync(() => {
const spyOnSearch = spyOn(component.searchChanged, 'emit');
tick();
fixture.detectChanges();
fixture.whenStable().then(() => {
component.searchInput.value = 'test';
component.clear();
tick();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(spyOnSearch).toHaveBeenCalledWith('');
});
});
}));