angular - 业力 | 离子 | 未捕获的错误:未捕获的错误:未捕获(承诺中):TypeError:无法读取未定义的属性“getToken”
问题描述
在我的 Ionic 应用程序上运行单元测试时,在它测试应用程序是否初始化的 app.component.spec.ts 中,我收到以下错误:
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
这是我的单元测试代码(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();
});
});
这是错误中引用的代码(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
}
具体来说,它this.fcm.getToken().then
是错误消息中引用的那个。但是,我不完全确定如何处理这些信息。我只是想测试应用程序是否正在初始化,我并没有尝试专门进行测试来测试这个承诺。如果有人知道如何解决此错误,那将非常有帮助。
解决方案
您必须模拟fcm
才能拥有一个getToken
功能并使其返回一个承诺。
将您的 providers 数组更改为:
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
],
推荐阅读
- arrays - 更新 redux 数组中的多个项目
- android - 按钮未出现在基本活动中
- java - Hibernate - @Embeddable 与其自身的父关系
- php - 正确读取多个 CLOB 数据 - php / oracle
- android - 您能否确定用户是否刚刚使用生物识别技术解锁了移动设备?
- php - php 7.0 致命错误调用未定义的方法产品::
- powershell - 使用 PowerShell 将 csv 文件的内容发布到 Jira
- matlab - 从时域到频域
- angular - angular 5 为导入的模块提供共享服务
- r - 在 R 中的矩阵列表中的每个矩阵中绘制一列