Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 7 Unit testing Observable subscribe call

I've a GeoLocationService in my angular application like this.

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
        };
    });
  }
}

I want to unit test this service to ensure that the getPosition() function returns me a working Observable. Here's how my test looks like.

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();
      });
  }));
});

What happens here is that once I run the test the test is successful ( this is because the subscribe block inside the test is not run yet). On the chrome browser window that opens ( for viewing test results in karma ), I select Allow for the application to find my location, it is at this moment the subscribe block runs but by that time the it spec has already finished due to this reason I get a console error saying.

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

I don't know what is the recommended way to perform this test.

like image 986
Mj1992 Avatar asked Nov 15 '25 16:11

Mj1992


1 Answers

I was able to get it working using the following code.

  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();
    });
  });

For this the test waits until you Allow the browser window to get your location. If you wait for too long, it will throw a timeOut error. Good enough for me to test what I wanted.

like image 81
Mj1992 Avatar answered Nov 18 '25 09:11

Mj1992



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!