jeudi 16 janvier 2020

Jasmine spy not being called in callback. instead actual method is called

i am trying to mock a service method while writing test cases. i am actually trying to test the delete functionality. User clicks on the delete button and a popup is shown and if user confirms, service method to delete that item is called. following is the code to show dialog and delete item.

  deleteItem(item: E) {
    this.dataService.delete(id).subscribe(result => {
      let r = result;
      const index: number = this.items.findIndex(x => x.id == item.id);
      if (index !== -1) {
        this.items.splice(index, 1);
        this.items = [...this.items];
        this.changeDetectorRefs.detectChanges();
      }
    });
  }

  delete(item: E): void {
    this.deleteDialogRef = this.dialog.open(ConfirmDialogComponent, {
      disableClose: true,
      data: {
        confirmationType: "delete"
      }
    });

    this.deleteDialogRef.afterClosed().subscribe(action => {
      if (action) {
        this.deleteItem(item);
      }
    });
  }

in template:

<button name="delete" [disabled]="!IsDeletePermission" mat-icon-button color="warn"
          matTooltip="('GENERAL.ACTIONS.DELETE' | translate)" (click)="delete(item)">
          <mat-icon color="warn">delete</mat-icon>
        </button>

and here is my test case setup:

beforeEach(async(() => {

  TestBed.configureTestingModule({
    declarations: [
      UserpermissionListComponent,
      ConfirmDialogComponent
    ],
    imports: [
      TestingModuleIntegration,
      RouterTestingModule.withRoutes([
        { path: 'userpermission', component: UserpermissionListComponent }
      ])
    ],
    providers: [
      UserpermissionService,
      ChangeDetectorRef,
      { provide: MatDialogRef, useValue: {close: (dialogResult: any) => { }} },
    ]

  }).compileComponents();

}));

beforeEach(() => {
  fixture = TestBed.createComponent(UserpermissionListComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();
});

fit('should delete the item from list', async () => {
  component.IsDeletePermission = true;
  component.items = data;
  fixture.detectChanges();

  let tableRows = fixture.nativeElement.querySelectorAll('mat-row')
  let firstRowCells = tableRows[0].querySelectorAll('mat-cell');
  let deleteButtonCell = firstRowCells[firstRowCells.length - 1];
  let deleteButton = deleteButtonCell.querySelectorAll('button')[1];

  spyOn(component.dataService, "delete").and.returnValue(of(null));
  let itemsLength = component.items.length;
  deleteButton.click();
  component.deleteDialogRef.close(true);
  expect(component.items.length).toBe(itemsLength - 1);
});

now if directly call deleteItem() on button click it works fine and mocked method is called. but if i call delete() then it calls actual service method instead of mock. So how can i mock this service method in such a way that it's called in callbacks as well?

Aucun commentaire:

Enregistrer un commentaire