0
votes

EDIT/SOLUTION: I found the answer why $location was not injecting. I needed to update my angular-mocks.js file to latest 1.3. once I fixed that, It worked like a charm!

I am having a great difficulty in finding out what is wrong with this code snippet. I have a login page, after sucessfull login it redirects me to the protected resource page. Everything is working fine. expect the UNIT TESTING part.

Here is myTest

ddescribe("Login Controller", function () {
   var scope, controller, location, http, ControllerService, state;
    beforeEach(module('myApp'));
    beforeEach(inject(function ($httpBackend, $rootScope, $controller, $location) {
          scope= $rootScope.$new();
          http= $httpBackend;
          location = $location
          ControllerService= $controller;
    }));
    beforeEach(inject(function ($injector) {
        location = $injector.get('$location');
    }));

  iit("should do mock authentication", function () {
     http.expectPOST('http://127.0.0.1:7000/auth').respond('True');
     http.expectPOST('http://127.0.0.1:7000/obtain/').respond('4nd8n129dd01m1md8'); 
     Newcontroller = ControllerService("simpleController", {
                                            $location:location,                                                                 $scope:scope,
                                            tokenfactory:tokenfactory});
        scope.$digest();
        scope.login();
        http.flush();
        expect(scope.somedata).toBe('True');
      
    });
)};  

And here is my login() function

var app = angular.module('myApp',['ui.bootstrap','ui.router','ngCookies', 'UserValidation','restangular']);

app.controller ('simpleController',function($scope ,$http, $location, tokenfactory,loginusercheck, usernamefactory,Restangular){
  
  $scope.login = function(){
    // some login function
    //after post to login endpoint
    //change the page state to something else 
    
    $location.path('list'); // where list is the url to protected page 
    
    
    };
  })

Now when i run this using karma-jasmine test runner, I get error

typeError: undefined is not a function at $LocationProvider.$get

If I comment out the $location.path('list') and dont inject the $location in my test case = everything works fine. What am i doing wrong. I cant seem to inject $location. is there anyother wat to inject $location?

1
EDIT/SOLUTION: I found the answer why $location was not injecting. I needed to update my angular-mocks.js file to latest 1.3. once I fixed that, It worked like a charm! - Karan Kumar

1 Answers

0
votes

The first, obvious issue is that you cannot change $location.path in a unit test without mocking location. This is because karma depends on a web browser, and changing location actually navigates away from the test.

Here's something that might help you:

describe("Login Controller", function () {
   var scope, controller, location, http, ControllerService, state;
    beforeEach(module('myApp'm function($provide) {
        $provide.factory('$location', {
            path: undefined
        });
    }));
    beforeEach(inject(function ($httpBackend, $rootScope, $controller) {
          scope= $rootScope.$new();
          http= $httpBackend;
          ControllerService= $controller;
    }));

  it("should do mock authentication", inject(function ($location) {
     http.expectPOST('http://127.0.0.1:7000/auth').respond('True');
     http.expectPOST('http://127.0.0.1:7000/obtain/').respond('4nd8n129dd01m1md8'); 
     Newcontroller = ControllerService("simpleController", {                                                                 $scope:scope,
                                            tokenfactory:tokenfactory});
        scope.$digest();
        scope.login();
        http.flush();
        expect(scope.somedata).toBe('True');
        expect($location.path).toEqual('list');
    });
))};