Угловое 7 модульное тестирование Наблюдаемый вызов подписки - PullRequest
0 голосов
/ 02 июля 2019

У меня есть GeoLocationService в моем угловом приложении, как это.

import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Observable";

@Injectable()
export class GeoLocationService {
  coordinates: any;

  constructor() {}

  public getPosition(): Observable<Position> {
    return Observable.create(observer => {
      navigator.geolocation.watchPosition((pos: Position) => {
        observer.next(pos);
      }),
        () => {
          console.log("Position is not available");
        },
        {
          enableHighAccuracy: true
        };
    });
  }
}

Я хочу провести модульное тестирование этой службы, чтобы функция getPosition() вернула мне рабочий Observable. Вот как выглядит мой тест.

import { TestBed, fakeAsync } from "@angular/core/testing";

import { GeoLocationService } from "./geo-location.service";
import { take } from "rxjs/operators";

describe("GeoLocationService", () => {
  let service: GeoLocationService;
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [GeoLocationService]
    });
    service = TestBed.get(GeoLocationService);
  });


  it("should get observable value", fakeAsync((done: DoneFn) => {
    service
      .getPosition()
      .subscribe(value => {
        expect(value.coords).not.toBeUndefined();
        expect(value.coords).not.toBeNaN();
        expect(value.coords).not.toBeNull();
        done();
      });
  }));
});

В данном случае происходит то, что после запуска теста тест проходит успешно (это потому, что блок subscribe внутри теста еще не запущен). На открывшемся chrome browser window (для просмотра результатов испытаний в карме) я выбираю Allow для приложения, чтобы найти мое местоположение, в этот момент запускается блок subscribe, но к этому времени спецификация it имеет уже закончил, по этой причине я получаю поговорку console error

Uncaught Error: 'expect' was used when there was no current spec, this could be because an asynchronous test timed out.

Я не знаю, каков рекомендуемый способ выполнения этого теста. Я буду очень признателен, если кто-нибудь сможет мне помочь.

Ответы [ 2 ]

1 голос
/ 02 июля 2019

Вы можете использовать tick(), который подделывает тест как синхронный: -)

  it("should get observable value", fakeAsync((done: DoneFn) => {
    let matchValue = {coords: null};
    service
      .getPosition()
      .subscribe(value => {
        matchValue = value;
      });
      tick(2000); // whatever fits your needs
      expect(matchValue.coords).not.toBeUndefined();
      expect(matchValue.coords).not.toBeNaN();
      expect(matchValue.coords).not.toBeNull();
      done();
  }));
0 голосов
/ 02 июля 2019

Я смог заставить его работать, используя следующий код.

  it("should get current user coordinates", (done: DoneFn) => {
    let position: any;
    service.getPosition().subscribe(value => {
      position = value;
      expect(position.coords).not.toBeUndefined();
      expect(position.coords).not.toBeNaN();
      expect(position.coords).not.toBeNull();
      done();
    });
  });

Для этого тест ждет, пока вы не Allow откроете окно браузера, чтобы узнать ваше местоположение.Если вы будете ждать слишком долго, это приведет к ошибке timeOut.Достаточно хорошо для меня, чтобы проверить, что я хотел.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...