此自定义验证指令是官方角度网站上提供的示例。 http://docs.angularjs.org/guide/forms会 检查文本输入是否为数字格式。
var INTEGER_REGEXP = /^\-?\d*$/; app.directive('integer', function() { return { require: 'ngModel', link: function(scope, elm, attrs, ctrl) { ctrl.$parsers.unshift(function(viewValue) { if (INTEGER_REGEXP.test(viewValue)) { // it is valid ctrl.$setValidity('integer', true); return viewValue; } else { // it is invalid, return undefined (no model update) ctrl.$setValidity('integer', false); return undefined; } }); } }; });
为了对该代码进行单元测试,我编写了以下代码:
describe('directives', function() { beforeEach(module('exampleDirective')); describe('integer', function() { it('should validate an integer', function() { inject(function($compile, $rootScope) { var element = angular.element( '<form name="form">' + '<input ng-model="someNum" name="someNum" integer>' + '</form>' ); $compile(element)($rootScope); $rootScope.$digest(); element.find('input').val(5); expect($rootScope.someNum).toEqual(5); }); }); }); });
然后我得到这个错误:
Expected undefined to equal 5. Error: Expected undefined to equal 5.
我到处都放置了print语句以查看发生了什么,而且该指令似乎从未被调用过。测试像这样的简单指令的正确方法是什么?
另一个答案的测试应写为:
describe('directives', function() { var $scope, form; beforeEach(module('exampleDirective')); beforeEach(inject(function($compile, $rootScope) { $scope = $rootScope; var element = angular.element( '<form name="form">' + '<input ng-model="model.somenum" name="somenum" integer />' + '</form>' ); $scope.model = { somenum: null } $compile(element)($scope); form = $scope.form; })); describe('integer', function() { it('should pass with integer', function() { form.somenum.$setViewValue('3'); $scope.$digest(); expect($scope.model.somenum).toEqual('3'); expect(form.somenum.$valid).toBe(true); }); it('should not pass with string', function() { form.somenum.$setViewValue('a'); $scope.$digest(); expect($scope.model.somenum).toBeUndefined(); expect(form.somenum.$valid).toBe(false); }); }); });
请注意,$scope.$digest()now是在之后调用的$setViewValue。这会将表单设置为“脏”状态,否则将保持“原始”状态,这可能不是您想要的。
$scope.$digest()
$setViewValue