Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit test Angular 5 - expect the Dialog to be closed

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.

like image 786
Marcos Avatar asked Feb 14 '18 08:02

Marcos


2 Answers

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.

like image 133
DerrickF Avatar answered Sep 30 '22 01:09

DerrickF


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

spyOn(component.dialogRef, 'close');
like image 42
Bitzu Avatar answered Sep 30 '22 00:09

Bitzu