如何测试角度控制器(业力+茉莉+角度模拟)?

时间:2017-03-07 17:06:06

标签: javascript angularjs unit-testing karma-jasmine angular-mock

我想用业力测试我的角色控制器' LoginOutCtrl', 用AMD风格编码的控制器:

define(["myapp-run"], function (app) {
    var SetAuthCtrl=["$scope","$rootScope","$location","USER_ROLES","AUTH_EVENTS","Auth", function ($scope, $rootScope,$location,USER_ROLES,AUTH_EVENTS,Auth) {
        $rootScope.setCurrentUser = function (user) {
            $rootScope.currentUser = user;
        };      
        $scope.userRoles = USER_ROLES;
        $scope.isAuthorized = Auth.isAuthorized;

    }]; 
    var LoginOutCtrl=["$scope","$rootScope","$location","AUTH_EVENTS","Auth", function ($scope, $rootScope,$location,AUTH_EVENTS,Auth) {
        $scope.logout = function () {

              Auth.logout().then(function (rs) {
                  if(rs.error){
                      var msg=rs.msg;
                      if(msg==="user not login"){
                          $rootScope.$broadcast(AUTH_EVENTS.logoutSuccess);
                          $rootScope.setCurrentUser(null);
                          $location.path('/');
                      }else{
                          $rootScope.$broadcast(AUTH_EVENTS.logoutFailed);
                      }
                  }else{
                      $rootScope.$broadcast(AUTH_EVENTS.logoutSuccess);
                      $rootScope.setCurrentUser(null);
                      $location.path('/');
                  }
               }, function (httpResponse) {
                      console.dir(httpResponse);
                      $rootScope.$broadcast(AUTH_EVENTS.logoutFailed);
              });
          }; 
    }];


    }];

    app.controller('LoginOutCtrl',LoginOutCtrl);
    app.controller('SetAuthCtrl',SetAuthCtrl);
    return {
        'LoginOutCtrl':LoginOutCtrl,
        'SetAuthCtrl':SetAuthCtrl
    }
});    

和我的业力单元测试文件:authSpec.js

define(["jquery","angularAMD","myapp-route", "angular-mocks"], function($,angularAMD,app) {
                describe('controllers/auth:SetAuthCtrl ', function() {
                    var $scope;
                    beforeEach(module('myapp'));
                    beforeEach(inject(function($rootScope, $controller) {
                      $scope = $rootScope.$new();
                      $controller('SetAuthCtrl', {'$scope': $scope});        
                    }));
                    it('should set setCurrentUser', function() {
                       expect($scope.setCurrentUser).toBeDefined();
                    });
                    it('should set userRoles', function() {
                       expect($scope.userRoles).toBeDefined();
                    });
                    it('should set isAuthorized', function() {
                       expect($scope.isAuthorized).toBeDefined();
                    });   
                });
                describe('controllers/auth:LoginOutCtrl-> ', function() {
                var $rootScope,$scope,$location,$controller,Auth,logoutDeferred;
                var mocklogout_success = {
                        delSessionid:'sessionid',delUserId:'userId',delUserName:'userName'
                };
                var mocklogout_success_usernotlogin = {
                        error:true,msg:'user not login'
                };
                var mocklogout_failed = {
                        error:true,msg:"del user-> "+'userName'+" session ->"+'sessionid'+"failed :"+'err'
                };

                beforeEach(module('myapp'));        
                beforeEach(inject(function($injector,_$q_) {      
                  $rootScope = $injector.get('$rootScope');
                  $scope = $rootScope.$new();
                  $location = $injector.get('$location');
                  $controller = $injector.get('$controller');      
                  AUTH_EVENTS=$injector.get('AUTH_EVENTS');
                  Auth = $injector.get('Auth');
                  $rootScope.setCurrentUser = function (user) {
                 $rootScope.currentUser = user;
                  };
                  logoutDeferred =_$q_.defer();       
                  spyOn(Auth, 'logout').and.returnValue(logoutDeferred.promise);
                  spyOn($location,'path');
                  spyOn($rootScope,'$broadcast').and.callThrough();
                  spyOn($rootScope,'setCurrentUser');
                  $controller('LoginOutCtrl', {
                      '$scope': $scope,'$rootScope' : $rootScope,         
                      '$location':$location,'AUTH_EVENTS':AUTH_EVENTS, 
                      'Auth': Auth});

                }));
                it('should have logout() function.', function() {
                       expect($scope.logout).toBeDefined();
                });
                it('logout_success', function() {
                       logoutDeferred.resolve(mocklogout_success);  
                       $rootScope.$digest();       
                       $scope.logout();            
                       expect($rootScope.$broadcast).toHaveBeenCalledWith(AUTH_EVENTS.loginSuccess);
         expect($rootScope.setCurrentUser).toHaveBeenCalledWith(null);
                       expect($location.path).toHaveBeenCalledWith("/");
                });
                it('logout_success_usernotlogin', function() {
                       logoutDeferred.resolve(mocklogout_success_usernotlogin);
                       $rootScope.$digest();           
                       $scope.logout();            
                       expect($rootScope.$broadcast).toHaveBeenCalledWith(AUTH_EVENTS.loginSuccess);
         expect($rootScope.setCurrentUser).toHaveBeenCalledWith(null);         
                       expect($location.path).toHaveBeenCalledWith("/");
                });
                it('logout_failed', function() {
                       logoutDeferred.resolve(mocklogout_failed);
                       $rootScope.$digest();
                       $scope.logout();       
                       expect($rootScope.$broadcast).not.toHaveBeenCalledWith(AUTH_EVENTS.logoutFailed);
                });
            });
            });

如您所见,我想检查$ scope.logout函数是否成功执行:

the event $rootScope.$broadcast , the function setCurrentUser
the service $location.path HaveBeenCalledWith correct params

Note: inject param 'AUTH_EVENTS' is app.constant
Note: inject param 'AUTH' is app.service which provide some auth-works and i have mocked it with $q.defer()

但我在karma控制台上遇到了以下错误:

03 03 2017 15:32:38.618:INFO [watcher]: Changed file "D:/Git/gitlab/myapp/test/unit/controllers/authSpec.js".
Chrome 55.0.2883 (Windows 7 0.0.0) controllers/auth:LoginOutCtrl->  logout_success FAILED
    Expected spy $broadcast to have been called with [ 'auth-login-success' ] but actual calls were [ '$locationChangeStart', 'http://server/', 'h
            ttp://server/', undefined, undefined ], [ '$locationChangeSuccess', 'http://server/', 'http://server/', undefined, undefined ].
                        at Object.<anonymous> (test/unit/controllers/authSpec.js:9:3866)
    Expected spy setCurrentUser to have been called with [ null ] but it was never called.
                        at Object.<anonymous> (test/unit/controllers/authSpec.js:9:3986)
    Expected spy path to have been called with [ '/' ] but actual calls were [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [
            ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [ '/myapp/home/pageNotFound' ].
                        at Object.<anonymous> (test/unit/controllers/authSpec.js:9:4075)
Chrome 55.0.2883 (Windows 7 0.0.0) controllers/auth:LoginOutCtrl->  logout_success_usernotlogin FAILED
    Expected spy $broadcast to have been called with [ 'auth-login-success' ] but actual calls were [ '$locationChangeStart', 'http://server/', 'h
            ttp://server/', undefined, undefined ], [ '$locationChangeSuccess', 'http://server/', 'http://server/', undefined, undefined ].
                        at Object.<anonymous> (test/unit/controllers/authSpec.js:9:4505)
    Expected spy setCurrentUser to have been called with [ null ] but it was never called.
                        at Object.<anonymous> (test/unit/controllers/authSpec.js:9:4625)
    Expected spy path to have been called with [ '/' ] but actual calls were [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [
            ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [  ], [ '/myapp/home/pageNotFound' ].
                        at Object.<anonymous> (test/unit/controllers/authSpec.js:9:4714)
Chrome 55.0.2883 (Windows 7 0.0.0): Executed 8 of 8 (2 FAILED) (0.983 secs / 0.125 secs)

以及该问题的更多消息

我用:

karma@1.5.0
karma-jasmine@1.1.0
jasmine-core@2.5.2
karma-requirejs@1.1.0
angular-mocks@1.6.2
angular-amd@0.2.1
angular@1.6.1
node@4.4.4  

我是一个新人(业力+茉莉+ angualr-mock),有什么我错过了吗?帮我解决这些错误......请帮忙!

0 个答案:

没有答案