Unit test Angular 5 - expect the Dialog to be closed

12,822

Solution 1

One way to fix it would be to supply a mock of the dialog class that has a close method instead of just supplying an empty object in your providers array. Something like:

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

The close method here does not actually do anything but you can check to see if it has been called at least.

Solution 2

The problem here is that you don't have a spy setup for what you want to do.

spyOn(component.dialogRef, 'close');
Share:
12,822
Marcos
Author by

Marcos

Updated on June 12, 2022

Comments

  • Marcos
    Marcos almost 2 years

    I have a component (which is a MatDialog component) whose one of the functions is simply to save some date and close itself on the end (the dialog), by simply calling "this.dialogRef.close(true);". So far so good. The problem lies on the Unit test. When I try to test this function, Karma throws an error "TypeError: this.dialogRef.close is not a function". I suppose it does not recognise the function close which is called in the dialog, because I must have forgotten to initiat this dialogRef in my spec.ts file somehow, but I have no idea how to proceed, considering the fact that there are not so much material on the web about configuring Material 2 components in spec.ts. My question is: How to get this test to recognize this dialogRef.close() function by the unit test.

    Some sample code below: 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();
    });
    

    Error thrown: TypeError: this.dialogRef.close is not a function

    I thank you in advance for the help.

  • asdf
    asdf over 4 years
    Same result: "close is not a function"