此自定义验证指令是官方角度网站上提供的示例。 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语句放在各处以查看发生了什么,看起来这个指令从未被调用过。 测试像这样的简单指令的正确方法是什么?
答案 0 :(得分:85)
其他答案的测试应写成:
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()
之后会调用$setViewValue
。这会将表单设置为“脏”状态,否则它将保持“原始状态”,这可能不是您想要的。
答案 1 :(得分:67)
我通过阅读角度应用代码https://github.com/angular-app/angular-app来解决这个问题 此视频也有助http://youtu.be/ZhfUv0spHCY?t=31m17s
我犯了两个错误:
这是更新版本。该指令是相同的,只是我改变的测试。
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);
$scope.$digest();
form = $scope.form;
}));
describe('integer', function() {
it('should pass with integer', function() {
form.somenum.$setViewValue('3');
expect($scope.model.somenum).toEqual('3');
expect(form.somenum.$valid).toBe(true);
});
it('should not pass with string', function() {
form.somenum.$setViewValue('a');
expect($scope.model.somenum).toBeUndefined();
expect(form.somenum.$valid).toBe(false);
});
});
});
答案 2 :(得分:2)
我测试我的自定义指令在对象中搜索&#34; $ error&#34;自定义验证的名称。例如:
'use strict';
describe('Directive: validadorCorreo', function () {
// load the directive's module
beforeEach(module('sistemaRegistroProCivilApp'));
var inputCorreo, formulario, elementoFormulario, scope, $compile;
beforeEach(inject(function ($rootScope, _$compile_) {
scope = $rootScope.$new();
$compile = _$compile_;
elementoFormulario = angular.element('<form name="formulario">' +
'<input type="text" name="correo" data-ng-model="correo" required data-validador-correo/>' +
'</form');
scope.correo = '';
elementoFormulario = $compile(elementoFormulario)(scope);
scope.$digest();
inputCorreo = elementoFormulario.find('input');
formulario = scope.formulario;
console.log(formulario.correo.$error);
}));
it('Deberia Validar si un correo ingresado en el input es correcto e incorrecto', inject(function ($compile) {
inputCorreo.val('eric+@eric.com').triggerHandler('input');
expect(formulario.correo.$error.email).toBe(true); //Here, the name of the custom validation appears in the $error object.
console.log(formulario.correo.$error);
inputCorreo.val('eric@eric.com').triggerHandler('input');
expect(formulario.correo.$error.email).toBeUndefined();//Here, the name of the custom validation disappears in the $error object. Is Undefined
console.log(formulario.correo.$error.email)
}));
});
我希望我能帮到你!