Jasmine单元测试,如何触发ngx-modal-dialog的点击事件

Jasmine unit testing, how do I trigger the click event of ngx-modal-dialog

我正在开发一个 angular 应用程序,我正在使用 Jasmine 对该应用程序进行单元测试。

本应用使用ngx-modal-dialog(enter link description here)弹出对话框插件作为动态组件。

我想要的是触发确认或取消的点击事件,无论用户选择什么。

弹出对话框代码如下:

export class SomeComponent {

constructor(private modalService: ModalDialogService) {}
cancleEditConfirmDialog() {
   this.modalService.openDialog(this.viewRef, {
   title: 'Discard Changes ',
   childComponent: SimpleModalComponent,
   data: {
     text: 'Changes will not be saved. Do you want to proceed?'
   },
   settings: {
     closeButtonClass: 'close theme-icon-close'
   },
   actionButtons: [
     {
       text: 'Discard',
       buttonClass: 'btn btn-success',
       onAction: () => new Promise((resolve: any) => {
         // invoke delete
         // do something such as discard changes
         resolve()
       })
     },
     {
       text: 'Cancel',
       buttonClass: 'btn btn-danger',
       onAction: () => new Promise((resolve: any) => {
         // cancel and close popup
         setTimeout(() => {
           resolve();
         }, 20);
       })
     }
   ]
 });
}
}

how do i trigger the onAction: => () in the click event for discard button and for cancel button.

如果传递给 modalService 的 viewRef 是被测组件本身,则测试此模态对话框时会出现问题。这是因为模态对话框被添加到 viewRef 之外的 dom 中。因此,您只能使用 document.getElementById 访问测试中的元素,这是可能的,但您将没有机会使用所有这些不错的 debugElement 功能等等。

虽然有一个方法:如果在组件内部使用 div 作为 viewRef 没有问题,那么就可以完成测试。

stackblitz

这意味着您的模板需要如下所示:

模板

<div #parentDialog>
  <button type="button" (click)="cancleEditConfirmDialog()">Open Dialog</button>
</div>


如果是这种情况,组件将如下所示:

component.ts

  @ViewChild('parentDialog', {read: ViewContainerRef}) parentVCR;

  constructor(private modalService: ModalDialogService) {}

  cancleEditConfirmDialog() {
   this.modalService.openDialog(this.parentVCR, {
   title: 'Discard Changes ',
   childComponent: SimpleModalComponent,
   data: {
     text: 'Changes will not be saved. Do you want to proceed?'
   },
   settings: {
     closeButtonClass: 'close theme-icon-close'
   },
   actionButtons: [
     {
       text: 'Discard',
       buttonClass: 'btn btn-success',
       onAction: () => new Promise((resolve: any) => {
         // invoke delete
         // do something such as discard changes
         resolve()
       })
     },
     {
       text: 'Cancel',
       buttonClass: 'btn btn-danger',
       onAction: () => new Promise((resolve: any) => {
         // cancel and close popup
         setTimeout(() => {
            resolve();
         }, 20);
       })
     }
   ]});
 }



最后是您的测试用例:

测试

describe('AppComponent', () => {
  let fixture: ComponentFixture<AppComponent>;
  let component: AppComponent;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ModalDialogModule.forRoot()],
      declarations: [ AppComponent],
      schemas: [NO_ERRORS_SCHEMA]
    });

    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;

    fixture.detectChanges();
  });

  it('open dialog and cancel', fakeAsync(() => {
     let buttonDebugElems: DebugElement[] = fixture.debugElement.queryAll(By.css('button'));
    expect(buttonDebugElems.length).toEqual(1);
    expect(buttonDebugElems[0].nativeElement.innerText).toEqual('Open Dialog');

    // Open
    buttonDebugElems[0].triggerEventHandler('click', null);
    fixture.detectChanges();

    buttonDebugElems = fixture.debugElement.queryAll(By.css('button'));
    expect(buttonDebugElems.length).toEqual(3);

    expect(buttonDebugElems[1].nativeElement.innerText).toEqual('Discard');
    expect(buttonDebugElems[2].nativeElement.innerText).toEqual('Cancel');

    // cancel
    buttonDebugElems[2].triggerEventHandler('click', null);
    // needed to wait for the promise to resolve (20 needed due to the timeout of the cancel promise)
    tick(20);

    buttonDebugElems = fixture.debugElement.queryAll(By.css('button'));
    expect(buttonDebugElems.length).toEqual(1);

     // todo expect the things the action changed inside you component.
  }));

  it('open dialog and discard', fakeAsync(() => {
    let buttonDebugElems: DebugElement[] = fixture.debugElement.queryAll(By.css('button'));
    expect(buttonDebugElems.length).toEqual(1);
    expect(buttonDebugElems[0].nativeElement.innerText).toEqual('Open Dialog');

    // open
    buttonDebugElems[0].triggerEventHandler('click', null);
    fixture.detectChanges();

    buttonDebugElems = fixture.debugElement.queryAll(By.css('button'));
    expect(buttonDebugElems.length).toEqual(3);

    expect(buttonDebugElems[1].nativeElement.innerText).toEqual('Discard');
    expect(buttonDebugElems[2].nativeElement.innerText).toEqual('Cancel');

    // discard
    buttonDebugElems[1].triggerEventHandler('click', null);
    // needed to wait for the promise to resolve
    tick();

    buttonDebugElems = fixture.debugElement.queryAll(By.css('button'));
    expect(buttonDebugElems.length).toEqual(1);

    // todo expect the things the action changed inside you component.

  }));
});