【问题标题】:Inject mockService into an controller initialized from a directive将 mockService 注入从指令初始化的控制器中
【发布时间】:2016-04-26 13:54:18
【问题描述】:

我想对具有注入服务的控制器的指令进行单元测试(业力)。

见以下代码:

angular
    .module('webkr')
    .directive('userChangePassword', userChangePassword)
    .directive('compareTo', compareTo);


  /** @ngInject */
  function userChangePassword() {
    var directive = {
      restrict: 'E',
      scope: {},
      templateUrl: 'app/components/account/user_change_password/user_change_password.html',
      controller: changePasswordController,
      controllerAs: 'vm',
      bindToController: true
    };

    return directive;

    /** @ngInject */
    function changePasswordController($log, User, toastr) {
      var _this = this;

      //properties
      _this.formModel = {
        password: null,
        oldPassword: null,
        passwordRepetition: null
      };
      _this.formDefinition = {
        oldPassword: {
          name: 'oldPassword',
          label: 'Altes Passwort',
          placeholder: 'Altes Passwort',
          error: 'old password is required.'
        },
        password: {
          name: 'password',
          label: 'Neues Passwort',
          placeholder: 'Neues Passwort',
          error: 'new password is required.'
        },
        passwordRepetition: {
          name: 'passwordRepetition',
          label: 'Passwort bestätigen',
          placeholder: 'Passwort bestätigen',
          errorRequired: 'old password is required.',
          errorInvalid: 'Confirmation password is not equal new password.'
        }
      };

      //methods

      /**
       * cancel change password procedure
       */
      _this.cancelChangePassword = function () {
        //clean form data

        _this.changePasswordForm.$setPristine();
      };
      /**
       * submit change password
       */
      _this.submitPasswordChange = function () {
        if (_this.changePasswordForm.$invalid) {
          return;
        }

        User.changePassword(_this.formModel).then(function () {
          toastr.info('Password changed', JSON.stringify(_this.formModel));
          _this.cancelChangePassword();
        }, function (err) {
          toastr.error('Can`t change password');
          $log.error(err);
        });
      };
    }
  }

我的单元测试:

(function () {
  'use strict';

  describe('directive user_change_password', function () {
    var el, compile, rootScope, controller, mockUserService;

    beforeEach(function () {
      mockUserService = jasmine.createSpyObj('User', ['changePassword'])
      module('webkr', 'ngMockE2E')
    });

    beforeEach(inject(function ($compile, $rootScope, $controller, $q, $log, toastr) {
      compile = $compile;
      rootScope = $rootScope;

      //Service routes used in controller
      mockUserService.changePassword.and.returnValue($q.when("result"));

      //Compile element
      el = compile("<user-change-password></user-change-password>")(rootScope);
      rootScope.$digest();

      //Init controller
      controller = el.controller("userChangePassword", {
        $log: $log,
        User: mockUserService,
        toastr: toastr
      });

      //Spy on the form
      spyOn(controller.changePasswordForm, '$setPristine')

    }));

    it('should be compiled', function () {
      expect(el.html()).not.toEqual(null);
    });
  });
})();

不知何故,控制器未正确初始化。当我删除对象 ({$log:$log,User:mockUserService,toastr:toastr}) 时,一切正常。我在这里做错了什么?

【问题讨论】:

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


    【解决方案1】:

    模拟控制器依赖项适用于涉及$controller 的仅控制器规范。

    el.controller 是 getter 方法,has only 1 parameter:

    controller(name) - 检索当前元素的控制器或 它的父级。

    此时

      //Init controller
      controller = el.controller("userChangePassword", { ... });
    

    指令被编译并且它的控制器被实例化,这就是它的实例可以被检索到的原因。

    在测试指令控制器时模拟服务,坚持在注入器级别进行模拟:

    beforeEach(module('webkr', 'ngMockE2E', function ($provide) {
      $provide.factory('User', function ($q) {
         return { changePassword: jasmine.createSpy().and.returnValue($q.when("result")) };
      });      
    }));
    

    【讨论】:

      猜你喜欢
      • 2016-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-21
      相关资源
      最近更新 更多