简体   繁体   中英

Karma | Ionic | Uncaught Error: Uncaught Error: Uncaught (in promise): TypeError: Cannot read property 'getToken' of undefined

When running unit tests on my Ionic application, in app.component.spec.ts where it tests if the app initializes, I get these errors:

AppComponent should initialize the app

Uncaught Error: Uncaught (in promise): TypeError: Cannot read property 'getToken' of undefined
TypeError: Cannot read property 'getToken' of undefined

Failed: Uncaught (in promise): TypeError: Cannot read property 'getToken' of undefined
TypeError: Cannot read property 'getToken' of undefined

Here is the full error message

Here is my unit test code (app.component.spec.ts)

import { HttpClientTestingModule} from '@angular/common/http/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { TestBed, async } from '@angular/core/testing';

import { Platform } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { MagentoService } from './services/magento.service';

import { AppComponent } from './app.component';
import { NativeStorage } from '@ionic-native/native-storage/ngx';
import { Router } from '@angular/router';
import { NativeAudio } from '@ionic-native/native-audio/ngx';
import { Dialogs } from '@ionic-native/dialogs/ngx';
import { FCM } from '@ionic-native/fcm/ngx';

describe('AppComponent', () => {

  //let component = AppComponent;
  let statusBarSpy, splashScreenSpy, platformReadySpy, platformSpy;

  beforeEach(async(() => {
    statusBarSpy = jasmine.createSpyObj('StatusBar', ['styleDefault']);
    splashScreenSpy = jasmine.createSpyObj('SplashScreen', ['hide']);
    platformReadySpy = Promise.resolve();
    platformSpy = jasmine.createSpyObj('Platform', { ready: platformReadySpy,
      is: (type: string) => {( type === 'cordova' || type === 'desktop' || type === 'mobile' )},
    });
    TestBed.configureTestingModule({
      imports: [ HttpClientTestingModule ],
      declarations: [AppComponent],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
      providers: [
        { provide: StatusBar, useValue: statusBarSpy },
        { provide: SplashScreen, useValue: splashScreenSpy },
        { provide: Platform , useValue: platformSpy },
        { provide: NativeStorage },
        { provide: Router },
        { provide: NativeAudio },
        { provide: Dialogs },
        { provide: FCM }
      ],
    }).compileComponents();
  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  });

  it('should initialize the app', async () => {
    TestBed.createComponent(AppComponent);

    platformSpy.ready();
    statusBarSpy.styleDefault();
    splashScreenSpy.hide();

    expect(platformSpy.ready).toHaveBeenCalled();
    await platformReadySpy;
    expect(statusBarSpy.styleDefault).toHaveBeenCalled();
    expect(splashScreenSpy.hide).toHaveBeenCalled();
  });
});

And here is the code that is being referenced in the error (app.component.ts)

initializeApp() {
    this.platform.ready().then(() => {
      this.storageEngine.setItem('Platform', 'Android');
      this.statusBar.styleDefault();
      this.magentoService.getToken();

      this.fcm.getToken().then(token => {
        this.storageEngine.setItem('FCMToken', token);
      });
   //...snip
}

Specifically, it's the this.fcm.getToken().then that is being referenced in the error message. However, I'm not entirely sure what to do with this information. I'm only trying to test if the app is being initialized, I'm not trying to make a test specifically to test this promise. If anyone knows how to resolve this error, that would be incredibly helpful.

You have to mock fcm to have a getToken function and make it return a promise.

Change your providers array to this:

providers: [
        { provide: StatusBar, useValue: statusBarSpy },
        { provide: SplashScreen, useValue: splashScreenSpy },
        { provide: Platform , useValue: platformSpy },
        { provide: NativeStorage }, // these provides without useValue or useFactory seem weird to me
        { provide: Router },
        { provide: NativeAudio },
        { provide: Dialogs },
        { provide: FCM, useValue: { getToken: () => Promise.resolve(true) } } // mock FCM like so
      ],

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM