Spyon angular service方法返回意外的POST

时间:2015-07-25 20:37:27

标签: angularjs unit-testing jasmine angular-promise

我在控制器中有一个承诺,我正在尝试测试,我得到Error: Unexpected request: POST /v1/users

我正在试图窥探AuthService.changePassword,它会返回一个承诺并测试它是否被调用。不确定为什么它实际上正在进行POST调用...

控制器

  angular.module('example')
    .controller('ChangePasswordCtrl', ['AuthService', '$state',
      function(AuthService, $state) {
        var vm = this;
        vm.submitted = false;

        vm.submit = function(valid) {
          vm.submitted = true;

          if (!valid) return false;

          AuthService.changePassword(vm.email)
            .then(function(res) {
              $state.go('reset.confirmation');
            }, function(err) {
              vm.hasError = true;
            });

        };
      }
    ]);

单元测试

 describe('ChangePasswordCtrl', function() {
    var ctrl, scope, AuthService, $q, $state, deferred;

    beforeEach(module('example'));

    function _inject() {
      inject(function($controller, $rootScope, _AuthService_, _$state_, _$q_) {

        scope = $rootScope.$new();
        $state = _$state_;
        $q = _$q_;
        AuthService = _AuthService_;

        ctrl = $controller('ChangePasswordCtrl', {
          $scope: scope
        });
      });
    }

    describe('#submit', function() {
      beforeEach(function() {
        _inject();

        deferred = $q.defer();
        spyOn(AuthService, 'changePassword').and.returnValue(deferred.promise);
        spyOn($state, 'go');
      });

      describe('when email address is valid', function() {
        it('should call the changePassword method on the AuthService', function() {
          ctrl.submit(true);

          scope.$digest();

          expect(ctrl.submitted).toBe(true);
          expect(AuthService.changePassword).toHaveBeenCalled();
        });
      });
    });

  });

1 个答案:

答案 0 :(得分:1)

您的规范代码适合我(AuthService.changePassword的实际实现不会被调用):http://jsfiddle.net/7W2XB/7/

angular.module('example', [])
    .factory('AuthService', function() {
        return {
          changePassword: function() {
            throw new Error('Should not be called');
          }
        };
    })
    .controller('ChangePasswordCtrl', ['AuthService',
      function(AuthService) {
        var vm = this;
        vm.submitted = false;

        vm.submit = function(valid) {
          vm.submitted = true;

          if (!valid) return false;

          AuthService.changePassword(vm.email)
            .then(function(res) {
              $state.go('reset.confirmation');
            }, function(err) {
              vm.hasError = true;
            });

        };
      }
    ]);

describe('ChangePasswordCtrl', function() {
    var ctrl, scope, AuthService, $q, deferred;


    function _inject() {
      module('ui.router');
      module('example');
      inject(function($controller, $rootScope, _AuthService_, _$state_, _$q_) {

        scope = $rootScope.$new();
        $state = _$state_;
        $q = _$q_;
        AuthService = _AuthService_;

        ctrl = $controller('ChangePasswordCtrl', {
          $scope: scope
        });
      });
    }

    describe('#submit', function() {
      beforeEach(function() {
        _inject();

        deferred = $q.defer();
        spyOn(AuthService, 'changePassword').and.returnValue(deferred.promise);
      });

      describe('when email address is valid', function() {
        it('should call the changePassword method on the AuthService', function() {
          ctrl.submit(true);

          scope.$digest();

          expect(ctrl.submitted).toBe(true);
          expect(AuthService.changePassword).toHaveBeenCalled();
        });
      });
    });

  });

有些问题可能有助于使JSFiddle对您的情况更加真实:您使用的是什么版本的angular和Jasmine? - 你如何定义AuthService(大概是使用angular.factory)?