使用Karma/Jasmine测试Ionic 6时遇NullInjectorError:无Geolocation提供者
Ionic Native Geolocation测试报错:NullInjectorError: No provider for Geolocation!
报错信息
Failed: R3InjectorError(DynamicTestModule)[Geolocation -> Geolocation]:
NullInjectorError: No provider for Geolocation!
error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'Geolocation', 'Geolocation' ] })
NullInjectorError: R3InjectorError(DynamicTestModule)[Geolocation -> Geolocation]:
NullInjectorError: No provider for Geolocation!
当前测试代码配置
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { IonicModule, IonItem, Platform } from '@ionic/angular'; import { FoloLocation } from '../models/folo-location'; import { Geolocation } from '@ionic-native/geolocation/ngx'; import { HomePage } from './home.page'; describe('HomePage', () => { let component: HomePage; let fixture: ComponentFixture<HomePage>; let platform: Platform; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ HomePage ], imports: [IonicModule.forRoot()], providers: [ Geolocation ] }).compileComponents(); fixture = TestBed.createComponent(HomePage); component = fixture.componentInstance; platform = TestBed.inject(Platform); fixture.detectChanges(); }));
已尝试提供模拟对象,但问题仍未解决。
解决方法
1. 正确创建并注入Geolocation模拟对象
测试环境无法运行真实的Geolocation原生服务,必须用模拟对象替代。用Jasmine创建带方法的模拟对象,并预设返回值:
beforeEach(waitForAsync(() => { // 创建模拟对象,包含需要用到的方法 const geolocationMock = jasmine.createSpyObj('Geolocation', ['getCurrentPosition', 'watchPosition']); // 模拟getCurrentPosition方法的返回结果 geolocationMock.getCurrentPosition.and.returnValue(Promise.resolve({ coords: { latitude: 39.9042, longitude: 116.4074, accuracy: 15 } })); TestBed.configureTestingModule({ declarations: [ HomePage ], imports: [IonicModule.forRoot()], providers: [ { provide: Geolocation, useValue: geolocationMock } // 替换为模拟对象 ] }).compileComponents(); fixture = TestBed.createComponent(HomePage); component = fixture.componentInstance; platform = TestBed.inject(Platform); fixture.detectChanges(); }));
2. 检查全局模块配置
确认app.module.ts中已正确导入并提供Geolocation服务,虽然测试环境独立,但全局配置错误可能间接影响测试:
// app.module.ts import { Geolocation } from '@ionic-native/geolocation/ngx'; @NgModule({ declarations: [AppComponent], imports: [...], providers: [ Geolocation, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy } ], bootstrap: [AppComponent] }) export class AppModule { }
3. 排查嵌套依赖
如果HomePage依赖的其他组件/服务也注入了Geolocation,需要给这些依赖同样配置模拟对象,避免依赖链上的注入失败。
4. 结合Platform模拟设备环境
如果你的业务逻辑依赖平台类型(如仅在移动设备调用定位),可以同时模拟Platform服务:
// 在TestBed配置的providers中添加 { provide: Platform, useValue: { is: (type: string) => type === 'android' || type === 'ios', ready: () => Promise.resolve() } }
内容的提问来源于stack exchange,提问作者Erik Johnson
相关产品推荐
相关产品推荐

