我有一个组件(它是一个MatDialog组件),其中一个函数只是保存一些日期并在结尾(对话框)关闭它,只需调用“this.dialogRef.close(true);” 。到现在为止还挺好。 问题在于单元测试。当我尝试测试此函数时,Karma会抛出错误“TypeError:this.dialogRef.close不是函数”。我想它不会识别在对话框中调用的函数close,因为我必须忘记在我的spec.ts文件中以某种方式启动此dialogRef,但我不知道如何继续,考虑到事实并非如此关于在spec.ts中配置Material 2组件的网上有很多材料。我的问题是:如何让这个测试通过单元测试来识别这个dialogRef.close()函数。
下面的一些示例代码: timeRangeDialogComponent.ts
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
export class TimeRangeDialogComponent implements OnInit, OnDestroy {
constructor(public dialogRef: MatDialogRef<TimeRangeDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: any) {
}
saveCustomTimeRange(): void {
this.dialogRef.close(true);
}
}
TimeRangeDialogComponent.spec.ts
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TimeRangeDialogComponent ],
imports: [ FormsModule, MaterialModule, MatDatepickerModule ],
providers: [
{ provide: MatDialogRef, useValue: {} },
{ provide: MAT_DIALOG_DATA, useValue: [] } ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TimeRangeDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should call the function to close the dialog', () => {
component.saveCustomTimeRange();
expect(component.dialogRef.close()).toHaveBeenCalled();
});
抛出错误:TypeError:this.dialogRef.close不是函数
我事先感谢你的帮助。
答案 0 :(得分:3)
修复它的一种方法是提供具有close方法的对话框类的模拟,而不是仅在提供者数组中提供空对象。类似的东西:
// mock object with close method
const dialogMock = {
close: () => { }
};
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TimeRangeDialogComponent ],
imports: [ FormsModule, MaterialModule, MatDatepickerModule ],
providers: [
{ provide: MatDialogRef, useValue: dialogMock },
{ provide: MAT_DIALOG_DATA, useValue: [] } ]
})
.compileComponents();
}));
此处的close方法实际上并没有做任何事情,但您可以检查它是否至少被调用过。
答案 1 :(得分:0)
这里的问题是您没有想要进行的间谍设置。
spyOn(component.dialogRef, 'close');
答案 2 :(得分:0)
这是ngZone
的一个开放式错误和解决方案。尝试这样。
export class ErrorDialogService {
constructor(public dialog: MatDialog, private ngZone: NgZone) {
}
openDialog(dialogData: DialogData): any {
const dialogConfig = new MatDialogConfig();
dialogConfig.disableClose = true;
dialogConfig.autoFocus = true;
dialogConfig.data = dialogData;
let dialogRef;
this.ngZone.run(() => {
dialogRef = this.dialog.open(ErrorDialogComponent, dialogConfig);
});
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed');
});
}
}
和对话框
export class ErrorDialogComponent implements OnInit {
title = '';
data: DialogData;
constructor(private dialogRef: MatDialogRef<ErrorDialogComponent>,
@Inject(MAT_DIALOG_DATA) dialogData: DialogData) {
this.title = 'StarsWriters-Interceptor';
this.data = dialogData;
}
ngOnInit(): void {
}
close() {
console.log('CLOSE CLICKED'); // works
this.dialogRef.close(true); // Before running ErrorDialogService.openDialog without ngZone.run Fired but nothing happens.
}
}
答案 3 :(得分:0)
只需在close方法中添加间谍即可完成
。该问题在期望部分中也包含错误,它正在调用close函数,它应该是引用[ close 而不是 close()]。< / p>
it('should call the function to close the dialog', () => {
spyOn(component.dialogRef, "close");
component.saveCustomTimeRange();
expect(component.dialogRef.close).toHaveBeenCalled();
});