单元测试 Angular 5 - 期望对话框关闭

Mar*_*cos 6 unit-testing angular-material2 angular5

我有一个组件(它是一个 MatDialog 组件),它的功能之一就是通过简单地调用“this.dialogRef.close(true);”来保存一些日期并在最后(对话框)关闭自己。到现在为止还挺好。问题在于单元测试。当我尝试测试此函数时,Karma 会抛出错误“TypeError: this.dialogRef.close is not a function”。我想它不能识别在对话框中调用的函数 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);
 }
}
Run Code Online (Sandbox Code Playgroud)

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();
});
Run Code Online (Sandbox Code Playgroud)

抛出错误:TypeError: this.dialogRef.close is not a function

我预先感谢您的帮助。

小智 13

修复它的一种方法是提供具有 close 方法的对话框类的模拟,而不是仅在您的 providers 数组中提供一个空对象。就像是:

// 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();
}));
Run Code Online (Sandbox Code Playgroud)

这里的 close 方法实际上并没有做任何事情,但您至少可以检查它是否已被调用。