茉莉花单元测试,如何触发ngx-modal-dialog的click事件

时间:2019-03-01 06:46:54

标签: javascript angular unit-testing jasmine jasmine-jquery

我正在开发一个有角度的应用程序,并且正在使用Jasmine对应用程序进行单元测试。

应用程序将ngx-modal-dialogenter link description here)插件用于弹出对话框,例如确认框作为动态组件。

enter image 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);
       })
     }
   ]
 });
}
}
  

如何在点击事件中触发onAction: => ()放弃按钮   和取消按钮。

enter image description here enter image description here

1 个答案:

答案 0 :(得分:1)

如果传递给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.

  }));
});