Angular / Jasmin:测试时无法获取值

时间:2015-11-12 14:54:44

标签: javascript angularjs testing karma-runner karma-jasmine

我写了一个允许我更改密码的页面。代码有效,它可以完成我想要它做的所有事情,所以我开始编写测试。由于我在Angular测试中没有经验,这已经证明是非常困难的,我无法通过这个错误:

TypeError: 'undefined' is not an object (evaluating 'plan.apply')
    at /Users/denniegrondelaers/asadventure/myproject-web/src/users/controllers/userPasswordController.js:9
    at /Users/denniegrondelaers/asadventure/myproject-web/test/unitTests/specs/users/controllers/userPasswordControllerSpec.js:98

控制器: userPasswordController.js

users.controllers.controller('userPasswordController',
    ['$scope', 'Session', '$state', 'UserService', 'languages',
        function ($scope, Session, $state, UserService, languages) {

            $scope.languages = languages;
            $scope.password = "";
            $scope.notEqual = false;
            $scope.isSuccessful = false;

            $scope.changePassword = function() {
                var pw = {
                    userId: Session.getCurrentSession().userId,
                    oldPassword: encrypt($scope.password.oldPassword),
                    newPassword: encrypt($scope.password.newPassword),
                    newPasswordRepeat: encrypt($scope.password.newPasswordRepeat)
                };

                if (pw.newPassword === pw.newPasswordRepeat) {
                    $scope.notEqual = false;

                    UserService.setNewPassword(pw).then(function(res) {
                            $scope.formErrors = undefined;
                            $scope.isSuccessful = true;
                     }, function (error) {
                            $scope.formErrors = error.data;
                        }
                    );
                } else {
                    $scope.notEqual = true;
                }
            };

            var encrypt = function (password) {
                var encrypted = CryptoJS.md5(password);
                return encrypted.toString(CryptoJS.enc.Hex);
            };
        }
    ]
);

服务: userService.js

userService.setNewPassword = function (password) {
        return $http
            .put(EnvironmentConfig.endpointUrl +
            "/password/change", password)
    };

测试: userPasswordControllerSpec.js

describe('Users', function () {
    describe('Controllers', function () {
       fdescribe('userPasswordController', function () {

           var $scope,
               controller,
               $q,
               willResolve,
               mockSession,
               mockState,
               mockUserService,
               mockLanguages;

           beforeEach(function () {

               module('mysite.users.controllers');

               module(function ($provide) {
                   $provide.value('translateFilter', function (a) {
                       return a;
                   });

                   $provide.value('$state', function (a) {
                       return a;
                   });
               });

               mockSession = {
                   getCurrentSession: function () {
                       return {userId: 4};
                   }
               };

               mockState = {
                   params: {
                       id: 1
                   },
                   go: function () {

                   }
               };

               mockLanguages = {
                   getLanguages : function () {
                       var deferred = $q.defer();
                       deferred.resolve({
                           data: [{}]
                       });
                       return deferred.promise;
                   }
               };

               mockUserService = {
                   setNewPassword : function () {
                       var deferred = $q.defer();
                       if (willResolve) {
                           deferred.resolve({
                               data: [{}]
                           });
                       }
                       return deferred.promise;
                   }
               };

               inject(function (_$q_, $controller, $rootScope) {
                   controller = $controller;
                   $q = _$q_;
                   $scope = $rootScope.$new();
               });

               controller('userPasswordController', {$scope: $scope, Session: mockSession, $state: mockState,
                   UserService: mockUserService, languages: mockLanguages
                   });
               willResolve = true;
           });


           it('should change password', function () {
               spyOn(mockUserService, 'setNewPassword').and.callThrough();
               spyOn(mockState, 'go').and.callThrough();
               spyOn(mockSession, 'getCurrentSession').and.callFake();

               expect(mockUserService.setNewPassword).not.toHaveBeenCalled();
               expect($scope.isSubmitable()).not.toBeTruthy();

               $scope.compareStoreSelection = function () {
                   return true;
               };

               $scope.password = {
                   oldPassword: "123456",
                   newPassword: "password",
                   newPasswordRepeat: "password"
               };

               expect($scope.isSubmitable()).toBeTruthy();

>>>            $scope.changePassword();           <<< LOCATION OF ERROR, line 98
               expect(mockUserService.setNewPassword).toHaveBeenCalled();
               $scope.$apply();

           });
       });
    });
});

我已经标记了在测试中提供代码的行。

任何人都知道如何解决这个问题?一位同事建议改变我的控制器代码,但是我想保持原样,因为这个代码不应该被改变以便测试工作似乎合乎逻辑,对吗?

解决方案

Yarons建议将mockSession.getCurrentSession.callFake更改为mockSession.getCurrentSession.callThrough修复它!

0 个答案:

没有答案