如何在业力测试中注入离子地理定位?

How to inject Ionic Geolocation in karma tests?

我正在使用 ionic/angular 开发我的第一个非 hello-world 应用程序。

我创建了一个页面 (map.page.ts),它使用地理定位将地图置于正确位置的中心。 当我执行它时,它工作正常,但如果我尝试 运行 测试,即使是默认的:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';

import { MapPage } from './map.page';

describe('MapPage', () => {
  let component: MapPage;
  let fixture: ComponentFixture<MapPage>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ MapPage ],
      imports: [IonicModule.forRoot()]
    }).compileComponents();

    fixture = TestBed.createComponent(MapPage);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }));

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

失败并出现此错误:

Failed: R3InjectorError(DynamicTestModule)[Geolocation -> Geolocation]: NullInjectorError: No provider for Geolocation!

这是我的 map.page.ts:

import { Component, OnInit } from '@angular/core';
import { Geolocation } from '@ionic-native/geolocation/ngx';

@Component({
  selector: 'app-map',
  templateUrl: './map.page.html',
  styleUrls: ['./map.page.scss'],
})
export class MapPage implements OnInit {
  lat: number = 46.204391;
  lng: number = 6.143158;
  zoom: number = 15;

  constructor(private geolocation: Geolocation) {}

  ngOnInit() {
    this.geolocation
      .getCurrentPosition()
      .then((resp) => {
        this.lat = resp.coords.latitude;
        this.lng = resp.coords.longitude;
      })
      .catch((error) => {
        console.log('Error getting location', error);
      });
  }
}

并且在 map.module.ts:

中声明了地理位置
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

import { IonicModule } from '@ionic/angular';

import { MapPageRoutingModule } from './map-routing.module';

import { MapPage } from './map.page';
import { AgmCoreModule } from '@agm/core';
import { AgmJsMarkerClustererModule } from '@agm/js-marker-clusterer';
import { environment } from '../../../environments/environment';
import { Geolocation } from '@ionic-native/geolocation/ngx';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    IonicModule,
    MapPageRoutingModule,
    AgmJsMarkerClustererModule,
    AgmCoreModule.forRoot({
      apiKey: environment.googleMapsAPIKey,
    }),
  ],
  declarations: [MapPage],
  providers: [Geolocation],
})
export class MapPageModule {}

为什么 karma 无法加载这个?

它属于 MapPageModule,但未导入到 TestBed。因为它是您正在测试的同一组件的一部分,所以您可以在 providers 部分中单独指定它。

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';

import { MapPage } from './map.page';

describe('MapPage', () => {
  let component: MapPage;
  let fixture: ComponentFixture<MapPage>;

  beforeEach(async(() => {
    const geolocation = {
      getCurrentPosition: new Subject(),
    };
    TestBed.configureTestingModule({
      declarations: [ MapPage ],
      imports: [IonicModule.forRoot()],
      providers: [
        Geolocation, // <-- here, but better to mock.
//      {
//        providers: Geolocation,
//        useValue: geolocation,
//      },
      ],

    }).compileComponents();

    fixture = TestBed.createComponent(MapPage);
    component = fixture.componentInstance;
    fixture.detectChanges();
  }));

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});