Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test angularjs controller with $location service

I am trying to create a simple unit test that tests my show function.

I get the following error:

TypeError: Object #<Object> has no method 'show' 

It seems like $rootScope isn't the scope of the controller?

Here's my controller:

function OpponentsCtrl($scope, $location) {     $scope.show = function(url) {         $location.path(url);     } } OpponentsCtrl.$inject = ['$scope', '$location']; 

Here's my controller unit test:

describe('OpponentsCtrl', function() {     beforeEach(module(function($provide) {         $provide.factory('OpponentsCtrl', function($location){             // whatever it does...         });     }));      it('should change location when setting it via show function', inject(function($location, $rootScope, OpponentsCtrl) {         $location.path('/new/path');         $rootScope.$apply();         expect($location.path()).toBe('/new/path');          $rootScope.show('/test');         expect($location.path()).toBe('/test');     })); }); 
like image 247
simonvogensen Avatar asked Dec 01 '12 21:12

simonvogensen


People also ask

What is the purpose of $location service in AngularJS?

The $location in AngularJS basically uses a window. location service. The $location is used to read or change the URL in the browser and it is used to reflect that URL on our page. Any change made in the URL is stored in the $location service in AngularJS.

Is AngularJS code unit testable?

AngularJS is written with testability in mind, but it still requires that you do the right thing. We tried to make the right thing easy, but if you ignore these guidelines you may end up with an untestable application.

How pass data from controller controller to AngularJS?

Approach: To share data between the controllers in AngularJS we have two main cases: Share data between parent and child: Here, the sharing of data can be done simply by using controller inheritance as the scope of a child controller inherits from the scope of the parent controller.


1 Answers

This is how my test ended up working.

describe('OpponentsCtrl', function() {     var scope, rootScope, ctrl, location;      beforeEach(inject(function($location, $rootScope, $controller) {         location = $location;         rootScope = $rootScope;         scope = $rootScope.$new();         ctrl = $controller(OpponentsCtrl, {$scope: scope});     }));      it('should change location when setting it via show function', function() {         location.path('/new/path');         rootScope.$apply();         expect(location.path()).toBe('/new/path');          // test whatever the service should do...         scope.show('/test');         expect(location.path()).toBe('/test');      }); }); 
like image 139
simonvogensen Avatar answered Nov 03 '22 23:11

simonvogensen