Issue
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.
Solution
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
],
Answered By - AliF50
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.