簡體   English   中英

Angular 指令中的單元測試 $formatters

[英]Unit test $formatters in Angular directive

我有一個簡單的驗證器,可以根據正則表達式檢查輸入:

.directive('test', function () {
return {
    restrict: 'A',
    require: 'ngModel',
    link: function ($scope, element, attrs, ctrl) {

        ctrl.$setValidity('namePattern', true);

        function checkValid(name) {
            console.log('checkValid executed');
            if (!name || ctrl.$pristine) {
                ctrl.$setValidity('namePattern', true);
                return name;
            }
            var test = /^[A-Za-z0-9_-]+$/;
            ctrl.$setValidity('namePattern', test.test(name));
            return name;
        }

        // called when value changes via code/controller
        ctrl.$formatters.unshift(checkValid);
        // called when value changes in input element
        ctrl.$parsers.unshift(checkValid);
    }
  };
});

活生生的例子

我想對該指令進行單元測試,並具有以下內容:

function initState() {
  angular.mock.module('app');
  angular.mock.inject(function($compile, $rootScope, $timeout){
    $scope = $rootScope.$new();

    $rootScope.safeApply = function(cb) {
      $timeout(function() {
        $scope.$digest();
      });
    };

    $scope.model = {
      instanceName: ''
    };

    var tmpl = angular.element('<form name="form">' +
      '<input ng-model="model.instanceName" name="instanceName" test>' +
      '</form>'
    );

    element = $compile(tmpl)($scope);
    $scope.$apply();
    form = $scope.form;
  });
}
beforeEach(initState);

但是,對模型的更改不會觸發checkValid 我試過直接在模型上設置一個屬性:

it('should trigger a change resulting in an invalid state', function () {
  $scope.model.instanceName = 'this is an invalid name';
  $scope.$digest();
  expect(form.instanceName.$valid).to.be.false;
});

以及$modelValue

it('should trigger a change resulting in an invalid state', function () {
  form.instanceName.$modelValue = 'this is an invalid name';
  $scope.$digest();
  expect(form.instanceName.$valid).to.be.false;
});

我也嘗試通過element.triggerHandler觸發input事件。

如何觸發模型更改以便checkValid通過$formatters運行?

(這是使用 Angular 1.2.23)

看起來您的指令將輸入設置為有效,如果它是原始的。 在您編寫的單元測試的情況下,它始終是原始的,因為用戶還沒有與之交互。

如果您希望指令繼續現在的狀態,那么在測試測試中,您可以強制輸入不是原始的:(我在這里使用 Jasmine)

it('should trigger a change resulting in an invalid state', function () {
  $scope.model.instanceName = 'this is an invalid name';
  form.instanceName.$pristine = false;
  $scope.$digest();
  expect(form.instanceName.$valid).toEqual(false);
});

這可以在http://plnkr.co/edit/TEd91POjw9odNHSb6CQP?p=preview上看到

由於您的指令明確假定輸入對於處於原始狀態的輸入的模型更改有效,因此實際上我認為更有價值的測試是明確測試:

it('should ignore invalid values on a pristine input', function () {
  $scope.model.instanceName = 'this is an invalid name';
  form.instanceName.$setPristine();
  $scope.$digest();
  expect(form.instanceName.$valid).toEqual(true);
});

通過引用表單名稱和輸入名稱來使用$setViewValue

$scope.form.instanceName.$setViewValue('hello');

然后斷言。

expect($scope.model.instanceName).toEqual('something');
expect($scope.form.instanceName.$valid).toBe(true);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM