How to fake return calls from the geolocator in jasmine

I have a function that calls the geolocator and i don't know how to test this function. I've tried spying on the geolocator and returning fake data but with no success, the original function is still used and so i would have to wait and i couldn't use mock data.

// this doesn't work        
var navigator_spy = spyOn( navigator.geolocation, 'getCurrentPosition' ).andReturn( {
    coords : {
        latitude : 63,
        longitude : 143
    }
} );

How can I do this?

Answers:

Answer

When you call the geolocation code, it looks like this:

  navigator.geolocation.getCurrentPosition(onSuccess, onError);

This means that you're calling it and passing it functions:

  function onSuccess(position) {
      // do something with the coordinates returned
      var myLat = position.coords.latitude;
      var myLon = position.coords.longitude;
  }

  function onError(error) {
      // do something when an error occurs
  }

So, if you wanted to spy on it using jasmine returning a value, you'd want call the success function using the first argument of the original call like this:

  spyOn(navigator.geolocation,"getCurrentPosition").andCallFake(function() {
         var position = { coords: { latitude: 32, longitude: -96 } };
         arguments[0](position);
  });

If you wanted to make it look like an error was returned, you'd want to call the error function using the second argument of the original call like this:

  spyOn(navigator.geolocation,"getCurrentPosition").andCallFake(function() {
         arguments[1](error);
  });

Edit to show full example:

This is the function you are using Jasmine to test:

  function GetZipcodeFromGeolocation(onSuccess, onError) {
        navigator.geolocation.getCurrentPosition(function(position) {
              // do something with the position info like call
              // an web service with an ajax call to get data
              var zipcode = CallWebServiceWithPosition(position);
              onSuccess(zipcode);
        }, function(error) {
              onError(error);
        });
  }

This would be in your spec file:

  describe("Get Zipcode From Geolocation", function() {
        it("should execute the onSuccess function with valid data", function() {
              var jasmineSuccess = jasmine.createSpy();
              var jasmineError = jasmine.createSpy();

              spyOn(navigator.geolocation,"getCurrentPosition").andCallFake(function() {
                     var position = { coords: { latitude: 32.8569, longitude: -96.9628 } };
                     arguments[0](position);
              });

              GetZipcodeFromGeolocation(jasmineSuccess, jasmineError);

              waitsFor(jasmineSuccess.callCount > 0);

              runs(function() {
                    expect(jasmineSuccess).wasCalledWith('75038');
              });
        });
  });

At this point, when you run the spec, it will tell you that your web service gave you the proper zip code for the latitude and longitude you supplied if your web service works properly.

Answer

Ah wait, maybe you HAVE to create the spy within your beforeEach block because Jasmine restores spies automatically after each test case. if you did something like:

var navigator_spy = spyOn( navigator.geolocation, 'getCurrentPosition' )

it("should stub the navigator", function() {
   // your test code
});

the spy is already restored when you want to test it. Use this instead:

beforeEach(function() {
    this.navigatorSpy = spyOn( navigator.geolocation, 'getCurrentPosition' )
});

it("should work now since the spy is created in beforeEach", function() {
    // test code
});

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.