Javascript Angular指令中的单元测试$formatters
我有一个简单的验证器,可以根据正则表达式检查输入:Javascript Angular指令中的单元测试$formatters,javascript,angularjs,unit-testing,Javascript,Angularjs,Unit Testing,我有一个简单的验证器,可以根据正则表达式检查输入: .directive('test', function () { return { restrict: 'A', require: 'ngModel', link: function ($scope, element, attrs, ctrl) { ctrl.$setValidity('namePattern', true); function checkValid(name) {
.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);
以及与$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;
});
我还尝试通过元素.triggerHandler
触发输入
事件
如何触发模型更改,以便通过$formatters
运行checkValid
(这是使用Angular 1.2.23)通过引用表单名称和输入名称来使用
$setViewValue
$scope.form.instanceName.$setViewValue('hello');
然后断言
expect($scope.model.instanceName).toEqual('something');
expect($scope.form.instanceName.$valid).toBe(true);
看起来您的指令将输入设置为有效,如果它是原始的。在您编写的单元测试中,它始终是原始的,因为用户没有与它交互 如果您希望指令继续保持现在的状态,那么在测试中您可以强制输入不是原始的:(我在这里使用Jasmine) 可以看出,这一点正在发挥作用 由于您的指令明确假设输入在原始状态下对输入的模型更改有效,因此实际上我认为一个更有价值的测试是明确测试:
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
触发$parser和$validator,而不是$formatters:如果upvote/accept不可靠,则表示歉意-因此的应用程序出现问题。现在应该解决了。谢谢
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);
});
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);
});