You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 16:51:26