【发布时间】:2018-06-25 12:19:34
【问题描述】:
我在 Angular (1.2.29) 中构建了一个新指令,并尝试使用 karma 对其进行测试,但是在检查该字段是否无效时遇到了一些问题,它似乎始终有效。
这是我的指令:
var EmailOrUrlValidation = function emailOrUrlValidation() {
console.log("on directive 0");
return {
require: 'ngModel',
restrict: 'A',
scope: {
checkDirty: '=validationCheckDirty'
},
link: function (scope, element, attrs, ctrl) {
console.log("on directive 1");
scope.$watch(function () {
scope.checkDirty = scope.checkDirty ? true : false;
element.attr('maxlength', 50);
ctrl.$parsers.unshift(validateEmailOrUrl);
ctrl.$formatters.unshift(validateEmailOrUrl);
});
function validateEmailOrUrl(value) {
console.log("on directive 2");
var urlRegexp = "myurlregex";
var emailPattern = "myemailregex";
if (!value) {
ctrl.$setValidity("valid", true);
} else if (scope.checkDirty && !ctrl.$dirty) {
ctrl.$setValidity("valid", true);
} else {
var emailRegex = new RegExp(emailPattern);
var emailOrUrlValid = urlRegexp.test(value) || emailRegex.test(value);
ctrl.$setValidity("valid", emailOrUrlValid);
}
return value;
}
}
};
};
this.app = angular.module('shared.validations', [])
.directive('emailOrUrlValidation', [emailOrUrlValidation])
这是我的单元测试(我按照这个例子https://stackoverflow.com/a/22772504/1031021):
describe('EmailOrUrlValidation tests', function () {
var $scope, form, element;
beforeEach(module("shared.validations"));
beforeEach(inject(function ($compile, $rootScope) {
$scope = $rootScope;
element = angular.element(
'<form name="form">' +
'<input data-ng-model="model.emailorurl" name="emailorurl" email-or-url-validation data-ng-required="true" validation-check-dirty="true" />' +
'</form>'
);
$scope.model = { emailorurl: null }
$compile(element)($scope);
form = $scope.form;
}));
describe('invalid url', function () {
it('should pass with valid url', function () {
form.emailorurl.$setViewValue('www.google.pt');
$scope.$digest();
expect(form.emailorurl.$invalid).to.be.false;
});
it('should not pass with invalid url', function () {
form.emailorurl.$setViewValue('testing');
$scope.$digest();
expect(form.emailorurl.$invalid).to.be.true;
});
});
});
但是其中一个断言失败了,因为 $invalid 总是假的......
我在函数 validateEmailOrUrl 中插入了一些日志,但它从未显示在我的控制台上,但是出现了函数之外的日志,我假设该函数没有被触发。
有人可以帮助我吗?这里有什么问题?
【问题讨论】:
-
文档建议
$setViewValue不会触发对模型验证器的调用。通过将值分配给$scope.model.emailorurl,尝试直接在测试中更新 ng-model。我还假设您已经用真正的正则表达式替换了urlRegexp和emailPattern? docs.angularjs.org/api/ng/type/… -
我尝试了您的解决方案,将 form.emailorurl.$setViewValue('testing') 替换为 $scope.model.emailorurl = "testing" 但仍然无效,我的指令中的函数 validateEmailOrUrl 是没有触发 :( 是的,我使用的是真正的正则表达式,我只是没有将它们粘贴到那里,因为它与问题无关并且会使问题太大......你还有其他解决方案吗?谢谢
标签: javascript angularjs unit-testing angularjs-directive