【问题标题】:How to click button element with Jasmine?如何使用 Jasmine 单击按钮元素?
【发布时间】:2021-06-24 05:37:24
【问题描述】:

我需要知道确认警报中发生了什么,但为此,我需要单击其中一个警报按钮。我没有成功。

ma​​in.component.ts

async signOut() {

    const {
      ["modules.organizations.main.sign_out.confirmation.title"]: title,
      ["modules.organizations.main.sign_out.confirmation.message"]: message,
      ["modules.organizations.main.sign_out.confirmation.cancel"]: cancel,
      ["modules.organizations.main.sign_out.confirmation.ok"]: ok,
    } = await this.translate.get([
      "modules.organizations.main.sign_out.confirmation.title",
      "modules.organizations.main.sign_out.confirmation.message",
      "modules.organizations.main.sign_out.confirmation.cancel",
      "modules.organizations.main.sign_out.confirmation.ok"
    ]).pipe(first()).toPromise()

    //I need to know what happens inside here after click in button.
    this.alert.confirmation(title, message, cancel, ok).afterClosed()
    .subscribe(async value => {

      if(!value.ok) return
      const loading = this.alert.loading()
      
      try {
        await this.messaging.deleteToken()
        await this.firestore.devices(this.user.uid).doc(this.messaging.uuid()).update({ deleted: true, deletedAt: this.firestore.now })
        await this.auth.signOut()
        loading.close()
      } catch (error) {
        loading.close()
        await this.auth.signOut()
      }
    })
  }

ma​​in.component.spec.ts

fdescribe('MainComponent', () => {
  let component: MainComponent;
  let fixture: ComponentFixture<MainComponent>;
  let bottomSheetMock: jasmine.SpyObj<any>;
  let alertServiceMock: jasmine.SpyObj<any>;
  let dialogRefSpy: jasmine.SpyObj<any>;
  let functionsServiceMock: jasmine.SpyObj<any>;
  let messagingServiceMock: jasmine.SpyObj<any>;
  let routerMock: jasmine.SpyObj<any>;
  let router: Router;
  let el: DebugElement;
  
  bottomSheetMock = jasmine.createSpyObj('MatBottomSheet', ['open']);
  bottomSheetMock.open.and.returnValue('true');

  dialogRefSpy = jasmine.createSpy();
  dialogRefSpy.component = {title: 'error', message: 'error'};
  dialogRefSpy.afterClosed = () => of(true);

  const matDialogSpy = jasmine.createSpyObj('MatDialog', [
    'open',
    'close',
  ]);
  matDialogSpy.open.and.returnValue(dialogRefSpy);
  matDialogSpy.close.and.returnValue(dialogRefSpy);

  beforeEach(waitForAsync(() => {
    messagingServiceMock = jasmine.createSpyObj('MessagingService', [
      'requestPermission'
    ]);
    messagingServiceMock.requestPermission.and.callThrough();

    routerMock = jasmine.createSpyObj('Router',[
      'navigate'
    ]);
    routerMock.navigate.and.returnValue(true);

    alertServiceMock = jasmine.createSpyObj('AlertService',[
      'message',
      'error',
      'input',
      'password',
      'loading',
      'confirmation'
    ]);
    alertServiceMock.error.and.returnValue(matDialogSpy.open(AlertComponent, {
      data: { 
        type: 'error',
        title: 'error',
        error: 'description'
      },
      disableClose: true
    }));
    alertServiceMock.input.and.returnValue(matDialogSpy.open(AlertComponent, {
      data: { 
        type: 'input', 
        title: 'title', 
        description: 'description'
      },
      disableClose: true
    }));
    alertServiceMock.confirmation.and.returnValue(matDialogSpy.open(AlertComponent, {
      data: { 
        type: 'confirmation', 
        title: 'title', 
        message: 'message', 
        cancel: 'cancel', 
        ok: true
      },
      disableClose: true
    }))
    alertServiceMock.loading.and.returnValue(matDialogSpy);
    alertServiceMock.message.and.callThrough();

    TestBed.configureTestingModule({
      imports: [
        NoopAnimationsModule,
        AngularFireModule.initializeApp(environment.firebase),
        AngularFirestoreModule,
        OverlayModule,
        RouterTestingModule,
        MatDialogModule,
        MatChipsModule,
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useClass: TranslateFakeLoader
          }
        })
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
      declarations: [
        MainComponent
      ],
      providers: [
        { provide: AlertService, useValue: alertServiceMock },
        { provide: MatDialog, useValue: matDialogSpy },
        { provide: MatBottomSheet, useValue: bottomSheetMock },
        { provide: Router, useValue: routerMock },
        { provide: MessagingService, useValue: messagingServiceMock },
        AuthService,
        TranslateService,
        UploadService,
        FormBuilder,
      ],
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MainComponent);
    bottomSheetMock = TestBed.inject(MatBottomSheet);
    alertServiceMock = TestBed.inject(AlertService);
    messagingServiceMock = TestBed.inject(MessagingService);
    component = fixture.componentInstance;
    el = fixture.debugElement;
  });

  afterEach(() => {
    fixture.destroy();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should display confirmation alert', fakeAsync(async () => {
    await component.signOut();
    await fixture.whenStable();
    let buttonDebugElems: DebugElement[] = fixture.debugElement.queryAll(By.css('.mat-button'));
    console.log('elements =>');
    console.log(buttonDebugElems); // Here, I have 0 elements.
    
    expect(await alertServiceMock.confirmation).toHaveBeenCalled();
  }));
});

Obs:生成警报时,会生成一个按钮元素。但即使在 debugElement 中搜索按钮,我也找不到任何东西。

【问题讨论】:

标签: angular typescript jasmine karma-jasmine


【解决方案1】:

尝试在fixture.whenStable 之后添加fixture.detectChanges 以运行更改检测,希望按钮将在那里。

  it('should display confirmation alert', fakeAsync(async () => {
    await component.signOut();
    await fixture.whenStable();
    fixture.detectChanges(); // add a fixture.detectChanges() for change detection to run
    // and maybe it will paint the button then.
    let buttonDebugElems: DebugElement[] = fixture.debugElement.queryAll(By.css('.mat-button'));
    console.log('elements =>');
    console.log(buttonDebugElems); // Here, I have 0 elements.
    
    expect(await alertServiceMock.confirmation).toHaveBeenCalled();
  }));

【讨论】:

  • 也许这也是一个问题,但我发现了一些没有渲染组件的东西。感谢您的回答。
【解决方案2】:

我设法解决了这个问题,组件没有被渲染,因为它有 *ngIf 返回 false。如果有人遇到同样的问题,请检查组件是否正在渲染:

console.log(fixture.debugElement);

在控制台中,您可以查看 html 的元素。

【讨论】:

    猜你喜欢
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 2019-03-19
    相关资源
    最近更新 更多