繁体   English   中英

麻烦的单元测试Angular指令

[英]Trouble unit testing Angular directive

我在弄清楚如何使用Jasmine对基本的Angular指令进行单元测试时遇到了一些麻烦。

基本上,该指令所做的就是检查两个密码输入是否相等,并设置

该指令如下所示:

angular.module('jhApp')
.directive('jhEquals', function() {

    return {
        restrict: 'A',
        require: '?ngModel',
        link: linker
    };

    function linker(scope, elem, attrs, ngModel) {
        if(!ngModel) {
            return false;
        }

        //watch own value and re-validate
        scope.$watch(attrs.ngModel, function() {
            validate();
        });

        //observe other value and re-validate on change
        attrs.$observe('jhEquals', function() {
            validate();
        });

        var validate = function() {
            var val1 = ngModel.$viewValue;
            var val2 = attrs.jhEquals;

            //set validity
            if(val1 && val2) {
                ngModel.$setValidity('jhEquals', !val1 || !val2 || val1 === val2);
            }
        };
    }

});

规格看起来像这样:

var scope,
    dirElement;

    beforeEach(function() {
        module('jhApp');
        module('templates');

        inject(function($rootScope, $compile) {
            scope = $rootScope;
            scope.user = {};

            dirElement = angular.element('<input id="password" type="password" name="password" ng-model="user.password" jh-equals="{{user.passwordconfirm}}"><input id="newpasswordconfirm" type="password" name="newpasswordconfirm" ng-model="user.passwordconfirm" jh-equals="{{user.password}}>');

            $compile(dirElement)(scope);
        });

        scope.$digest();
    });


it('should check if values are equal', function() {
    var passwordInput = dirElement.find('#password');
    var confirmPasswordInput = dirElement.find('#newpasswordconfirm');

    angular.element(passwordInput).val('testpassword').trigger('input');
    angular.element(confirmPasswordInput).val('nottestpassword').trigger('input');
    scope.$digest();

    //expect this to be invalid

});

passwordInput和ConfirmPasswordInput-在我进行console.logout时显示空对象,如果我在指令的validate()中检查val1和val2的值,则始终是未定义的。

所以我想这里的问题是我无法弄清楚如何选择要添加内容的输入。

您快要到了,但仍然存在一些小问题。

首先,您需要将指令放置在表单中以测试有效性。 还要检查最后绑定的jh-equals值是否缺少“”。

其次,jqlite find函数仅与元素选择器一起使用。 因此不可能选择dirElement.find('#testpassword')之类的元素,而是选择dirElement.find('input')。 他们之所以从jqlite中取消此功能,是为了使其更加轻巧。 相反,您可以创建dirElement.find('input')并通过索引选择所需的输入。 这似乎是一项艰巨的任务,但无论如何,大多数情况下,您都需要在jqlite中选择一个元素,该元素将位于dom树内的一小组中,例如在测试环境中或某个指令的内部厄运中。

最后,jqlite触发器称为triggerHandler,而不是触发器。

最终图片应该是这样的:

var scope, dirElement;

beforeEach(function() {
  module('jhApp');
  module('templates');

  inject(function($rootScope, $compile) {
    scope = $rootScope;
    scope.user = {};

    dirElement = $compile([
      '<form name="form">',
      '<input id="password" type="password" name="password"',
      ' ng-model="user.password" jh-equals="{{user.passwordconfirm}}" />',
      '<input id="newpasswordconfirm" type="password"',
      ' name="newpasswordconfirm" ng-model="user.passwordconfirm"',
      ' jh-equals="{{user.password}}" />',
      '</form>',
    ].join(''))(scope);
    scope.$digest();
  });

});

it('invalid  if the values are not equal', function() {
  var passwordInput = dirElement.find('input');
  var confirmPasswordInput = dirElement.find('input')[1];

  angular.element(passwordInput)
        .val('testpassword')
        .triggerHandler('input');
  angular.element(confirmPasswordInput)
        .val('nottestpassword')
        .triggerHandler('input');

  expect(scope.form.password.$invalid).toBe(true);
  expect(scope.form.password.$valid).toBe(false);
  expect(scope.form.password.$dirty).toBe(true);
  expect(scope.form.newpasswordconfirm.$invalid).toBe(true);
  expect(scope.form.newpasswordconfirm.$valid).toBe(false);
  expect(scope.form.newpasswordconfirm.$dirty).toBe(true);
});

it('valid  if the values are equal', function() {
  var passwordInput = dirElement.find('input');
  var confirmPasswordInput = dirElement.find('input')[1];

  angular.element(passwordInput)
        .val('testpassword')
        .triggerHandler('input');
  angular.element(confirmPasswordInput)
        .val('testpassword')
        .triggerHandler('input');

  expect(scope.form.password.$invalid).toBe(false);
  expect(scope.form.password.$valid).toBe(true);
  expect(scope.form.password.$dirty).toBe(true);
  expect(scope.form.newpasswordconfirm.$invalid).toBe(false);
  expect(scope.form.newpasswordconfirm.$valid).toBe(true);
  expect(scope.form.newpasswordconfirm.$dirty).toBe(true);

});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM