2

How to create a unit test of AngularJS $location service search() method?

I am using Jasmine+Karma for the test and AngularJS 1.3, and unit test is new to me :)

This is my service, which is working fine in production btw:

'use strict';
(function () {
angular.module('myApp')
   .service('myService', function ($location) {
      var _customerId = $location.search().id;
      /*jshint validthis:true */
      this.customerId = _customerId;
   });
})()

And this is my serviceSpec:

describe('Service: mySerivce', function(){

 var $location;

 beforeEach(module('myApp'));

 beforeEach(inject(function(_$location_){
  $location = _$location_;
 }));

 it('should get ID from url', function(){
   $location.path('/?id=1080');

   console.log($location.path()); // logs: '/?id=1080'
   console.log($location.search().id); // logs: undefined

   expect($location.search().id).toEqual(1080); // Returns err msg Expected undefined to equal 1080.
  })

});

When i use the search() method all I get is undefined? How can i use the method in a unit test?

5
  • Yes, then I'm still getting undefined. How can I test customerId instead? Commented Dec 8, 2014 at 15:31
  • First of all the test you are doing doesn't make much sense, you just tests $location.path itself which is already tested by AngularJS ;) for the $location.search() to reflect changes you might need to run $scope.$digest() or use spyOn to test the values Commented Dec 8, 2014 at 15:41
  • Will look into spyOn :) The reason i'm testing the search method, is because i want to use it for another test. The test is with $httpBackend, where I need the ID in a GET request. Commented Dec 8, 2014 at 15:54
  • 1
    to test controller that uses search you can do: spyOn($location, 'search').andReturn({id: 'mockedid'}) where you can check if calls to backend contains this mockedid Commented Dec 8, 2014 at 16:14
  • Cool, let me combine my comments into answer so you can accept it ;) Commented Dec 8, 2014 at 17:09

1 Answer 1

10

As per comments you need a $location.search().id to check controller functionality, in that case the best option is to use spyOn on injected service (any service really)

spyOn($location, 'search').andReturn({ id: mockedid })

and remember that some of the services/directives needs $scope.digest() to be triggered and change value

Sign up to request clarification or add additional context in comments.

2 Comments

Just a note for others who might read this, if you are working with Jasmine version 2.0+, it is .and.returnValue() and not .andReturn()
spyOn($location, 'search').andCallFake(function() {}); // also handy!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.