带弹出控制器的离子 5 单元测试

ionic 5 unit test with popover controller

我试图在我的 ionic 5 / angular 11 项目中监视 popover present 方法,但出现错误

Unhandled Promise rejection: Cannot read property 'then' of undefined

这是单元测试代码

describe('LoginPage', () => {

 let popoverSpy = jasmine.createSpyObj('Popover', ['create', 'present', 'onDidDismiss', 'dismiss']);
 let popoverCtrlSpy = jasmine.createSpyObj('PopoverController', ['create']);
 popoverCtrlSpy.create.and.callFake(function () {
  return popoverSpy;
 });

 beforeEach(waitForAsync(() => {
  TestBed.configureTestingModule({
   declarations: [LoginPage],
   imports: [
     IonicModule.forRoot(),
     TranslateModule.forChild(),
     ComponentsModule,
     TranslateModule.forRoot({
       loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
     })
   ],
   providers: [{ provide: PopoverController, useValue: popoverCtrlSpy }]
 }).compileComponents()

 it("check popover preset", () => {
  component.openEntitySelection();
  fixture.detectChanges();
  expect(popoverSpy.present).toHaveBeenCalled()
 })

}


private async openEntitySelection() {

 let popover = await this.popoverCtrl.create({
  component: PopoverPage
 });
 await popover.present();
 popover.onDidDismiss().then((response) => {
  //Handle response
 })

}

提前致谢!

看来你并不是在嘲笑 onDidDismiss 对 return 的承诺。您还需要使用 fixture.whenStablewaitForAsync 实用程序来等待 promise 在执行断言之前得到解决。

试试这个:

describe('LoginPage', () => {

 let popoverSpy = jasmine.createSpyObj('Popover', ['create', 'present', 'onDidDismiss', 'dismiss']);
 // !! -- Add this line -- !!
 // I am mock resolving it to a value of true, you can resolve it to any value
 popOverSpy.onDidDismiss.and.returnValue(Promise.resolve(true));
 // !! --- !!
 let popoverCtrlSpy = jasmine.createSpyObj('PopoverController', ['create']);
 popoverCtrlSpy.create.and.callFake(function () {
  return popoverSpy;
 });

 beforeEach(waitForAsync(() => {
  TestBed.configureTestingModule({
   declarations: [LoginPage],
   imports: [
     IonicModule.forRoot(),
     TranslateModule.forChild(),
     ComponentsModule,
     TranslateModule.forRoot({
       loader: { provide: TranslateLoader, useClass: TranslateFakeLoader }
     })
   ],
   providers: [{ provide: PopoverController, useValue: popoverCtrlSpy }]
 }).compileComponents()

 it("check popover preset", (done) => { // add done to let jasmine know you're done
  component.openEntitySelection();
  fixture.detectChanges();
  // you have to wait at least for one fixture.whenStable I am thinking
  // because we are returning a promise and we have to ensure that the promises
  // have completed before doing our assertion.
  fixture.whenStable().then(() => {
     expect(popoverSpy.present).toHaveBeenCalled();
     done();
  });
 });
}


private async openEntitySelection() {

 let popover = await this.popoverCtrl.create({
  component: PopoverPage
 });
 await popover.present();
 popover.onDidDismiss().then((response) => {
  //Handle response
 })

}