Michael Andorfer
Michael Andorfer

Reputation: 1800

Why is my jasmine spy not called?

I am currently writing a unit test for Geolocation API.

My Angular component looks as follow:

export class HeaderComponent {
  public lat: number = 56.713;
  public lng: number = 21.1644;
  public message: string;
  public messageType: string;

  public locationSuccess(data: any) {
    console.log(data);
    if (data) {
      if (data.coords) {
        this.lat = data.coords.latitude ? data.coords.latitude : this.lat;
        this.lng = data.coords.longitude ? data.coords.longitude : this.lng;
        this.messageType = 'success';
        this.message = 'You successfully granted us retrieving your location to ' +
                       'enhance your experience.';
      }
    }
  }

  public locationError() {
    console.log('error');
    this.message = 'Unfortunately we could not acquire your location which is recommended ' +
                   'for best user experience with our service.';
    this.messageType = 'danger';
  }

  public enableNavigatorLocation() {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        this.locationSuccess.bind(this),
        this.locationError.bind(this)
      );
    }
  }
}

And my unit test looks like this:

// synchronous beforeEach
beforeEach(() => {
  fixture = TestBed.createComponent(HeaderComponent);
  comp = fixture.componentInstance;
});

it('enableNavigatorLocation should call locationSuccess if successful', () => {
  const locationSuccess = jasmine.createSpy('locationSuccess');
  const locationError = jasmine.createSpy('locationError');

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

  comp.enableNavigatorLocation();

  expect(locationSuccess).toHaveBeenCalled();
});

My spy is not called and I have no idea what I am doing wrong. Could there be a problem with the function call via bind() in enableNavigatorLocation method?

I used this post from 2012 as a guideline

Upvotes: 1

Views: 3015

Answers (1)

Estus Flask
Estus Flask

Reputation: 222484

This happens because spying went wrong.

locationSuccess and locationError spies are local variables. They are never used. The fact that params in callFake have same names doesn't affect anything.

The proper way to do this is to stub navigator.geolocation.getCurrentPosition:

spyOn(navigator.geolocation, 'getCurrentPosition');

comp.enableNavigatorLocation();

expect(navigator.geolocation.getCurrentPosition).toHaveBeenCalledWith(
  comp.locationSuccess,
  comp.locationError
);

Upvotes: 1

Related Questions