将MatInput元素与@ViewChild一起使用,在运行spec时,生成的变量是不可赋值的



我在一个旧页面中有一个搜索组件,我正试图为它写一些测试,但它给了我一些悲伤的

这是模板

<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('');
});
});
}));

最新更新