I am trying to do unit test of my angular app with karma. I am getting some error. Am i missing something? A This my controller

(function () {
"use strict"
angular
    .module("myApp")

.controller("userCtrl",['$scope', '$state', 'userService', 'appSettings','md5','currentUser','$rootScope',
    function ($scope, $state, userService, appSettings,md5,currentUser, $rootScope) {

    $scope.login = function() {
        $scope.loading = true;
        if($scope.password != null){
        var user ={
            username:$scope.username,
            password:md5.createHash($scope.password)
        }

            var getData = userService.login(user);
            getData.then(function (response) {
                console.log(response);
                $scope.loading = false;

                currentUser.setProfile(user.username, response.data.sessionId);

                $state.go('videos');
            }, function (response) {
                console.log(response.data);
            });
        }else{
            $scope.msg = "Password field is empty!"
        }
    }
 }])
}());

This is my test codes

'use strict';

describe('userCtrl', function() {
  beforeEach(module('myApp'));
  var scope, userCtrl, apiService,q, deferred, currentUser;

describe('$scope.login', function(){
  beforeEach(function(){
        apiService = {
              login: function () {
                  deferred = q.defer();
                  return deferred.promise;
              };
            };
        });

beforeEach(inject(function($controller, $rootScope, $q, _currentUser_){
    var user ={name:'ali',password:'password'};
    scope = $rootScope.$new();
    q = $q;

    // The injector unwraps the underscores (_) from around the parameter names when matching
    userCtrl = $controller('userCtrl', {
        $scope:scope, 
        userService:apiService
      });
    //userService = _userService_;
    currentUser = _currentUser_;
  }));

    it('should call user service login', function() {
      spyOn(apiService, 'login').and.callThrough();
      scope.login();
      deferred.resolve(user);

      expect(apiService.login).toHaveBeenCalled();
    });

    it('checks the password field', function() {
      scope.login();
      expect(scope.msg).toEqual('Password field is empty!');
    });

});
});

And i am getting this error enter image description here

share|improve this question
    
You are not injecting the mock version of UserService into your controller. I can't really tell why from your code. You should try using the chrome debugger and stepping through the code as it runs the test. – Andrew Eisenberg Mar 29 at 2:29
    
Okay, I'll try that. – Sagar Maharjan Mar 29 at 3:40
    
it seems that you login method not get called so thats why it got undefined. use spyOn instead of doing this. – Jayant Patil Mar 31 at 6:26
    
you have missed to add // We have to call apply for this to work $scope.$apply(); – Jayant Patil Mar 31 at 6:32

If you have to test controller then use to spyon for service method and in case of service then use HttpBackend

    describe('Testing a Controller that uses a Promise', function() {
      var $scope;
      var $q;
      var deferred;

      beforeEach(module('search'));

      beforeEach(inject(function($controller, _$rootScope_, _$q_, searchService) {
        $q = _$q_;
        $scope = _$rootScope_.$new();

        // We use the $q service to create a mock instance of defer
        deferred = _$q_.defer();

        // Use a Jasmine Spy to return the deferred promise
        spyOn(searchService, 'search').and.returnValue(deferred.promise);

        // Init the controller, passing our spy service instance
        $controller('SearchController', {
          $scope: $scope,
          searchService: searchService
        });
      }));

      it('should resolve promise', function() {
        // Setup the data we wish to return for the .then function in the controller
        deferred.resolve([{
          id: 1
        }, {
          id: 2
        }]);

        // We have to call apply for this to work
        $scope.$apply();

        // Since we called apply, not we can perform our assertions
        expect($scope.results).not.toBe(undefined);
        expect($scope.error).toBe(undefined);
      });
    });

This for same using spyon for service method then use $appy method to make it work.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.