Angular 7 单元测试 Observable 订阅调用

Mj1*_*992 4 unit-testing karma-jasmine angular

我的角度应用程序中有一个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
        };
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

我想对该服务进行单元测试,以确保该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();
      });
  }));
});
Run Code Online (Sandbox Code Playgroud)

这里发生的情况是,一旦我运行测试,测试就会成功(这是因为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。

我不知道执行此测试的推荐方法是什么。

Mj1*_*992 5

我能够使用以下代码让它工作。

  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();
    });
  });
Run Code Online (Sandbox Code Playgroud)

为此,测试会等到您打开Allow浏览器窗口才能获取您的位置。如果等待时间太长,就会抛出超时错误。足以让我测试我想要的东西。