1

I'm trying to unit test with Jasmine a "promisified" version of the navigator.geolocation.getCurrentPosition method inside an Angular2 component (TypeScript):

async getCurrentPosition() {
    return new Promise((resolve, reject) => {
      navigator.geolocation.getCurrentPosition(resolve, reject, { enableHighAccuracy: true, timeout: 5000, maximumAge: 0 });
    });
  }

My test (aside of the component instantiation which is irrelevant) looks like this:

fit('should GEOLOCALIZE the BROWSER', async () => {
    const position = { coords: { latitude: 0, longitude: 0 } };
    const mockGeolocation: jasmine.SpyObj<Geolocation> = jasmine.createSpyObj('navigator.geolocation', ['getCurrentPosition']);
    mockGeolocation.getCurrentPosition.and.callFake(() => {
      return { then: () => position };
    });
    await component.getCurrentPosition();
    expect(navigator.geolocation.getCurrentPosition).toHaveBeenCalled();
  });

But I cannot make the test pass, the mocked geolocation seems to have no effect and the 5000ms timeout triggers, canceling the geolocation and failing the test:

Chrome Headless 92.0.4515.131 (Windows 10): Executed 1 of 273 (1 FAILED) (skipped 272) (0.402 secs / 0.113 secs)
TOTAL: 1 FAILED, 0 SUCCESS


1) should GEOLOCALIZE the BROWSER
     LoginComponent
     User denied Geolocation

I've seen other posts claiming that something like this would work:

spyOn(navigator.geolocation,'getCurrentPosition').and.callFake(function(locationSuccess, locationError) {
    const position = { coords: { latitude: 32, longitude: -96 } };
    arguments[0](position);
  });

But apparently, due to TypeScript strictness, I cannot use the arguments reserved keyword here. Is there an alternative?

Any idea of what am I doing wrong?

Thanks in advance.

fergardi
  • 35
  • 1
  • 2
  • 6

1 Answers1

0

Actually, diving into the TypeScript documentation, I found that there is, in fact, a TypeScript alternative for the classic arguments variable, the ellipsis syntax:

function multiply(n: number, ...m: number[]) {
  return m.map((x) => n * x);
}

Which indeed provided the desired result:

spyOn(navigator.geolocation, 'getCurrentPosition').and.callFake((...args: any[]) => {
      const position = { coords: { latitude: 0, longitude: 0 } };
      args[0](position);
    });

And the test is passing now:

LoginComponent
    √ should GEOLOCALIZE the BROWSER

Chrome Headless 92.0.4515.131 (Windows 10): Executed 1 of 274 (skipped 273) SUCCESS (0.559 secs / 0.281 secs)
TOTAL: 1 SUCCESS

May this information help somebody else!

fergardi
  • 35
  • 1
  • 2
  • 6