问题
我正在尝试测试一些指令(下面的代码)。其中之一是“电子邮件”(在代码(挪威语))指令中称为“epost”。解决这个问题应该适用于所有这些解决方案,所以我暂时保留这个解决方案。
技术:Angularjs,Jasmine,Requirejs,(在Chrome中运行的咕噜咕噜和业力)
该指令以两种方式验证电子邮件地址;在升档和模糊。我可以毫无问题地测试升档,你可以在下面的测试中看到,但我无法弄清楚如何模拟模糊,因此指令中的bind('blur')会运行。
我做了什么
我试图抓住这样的编译元素:
elem = angular.element(html);
element = $compile(elem)($scope);
然后在测试中我尝试了几种排列,以便在指令中的bind函数内部使用控制台日志来触发模糊。以下都不适用。它不会触发。
elem.trigger('blur');
element.trigger('blur');
elem.triggerHandler('blur');
element.triggerHandler('blur');
element.blur();
elem.blur();
我基于此注入和设置:To test a custom validation angularjs directive
angularjs中的电子邮件指令包含在requirejs
中define(function() {
var Directive = function() {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
var pattern = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/;
elem.bind('blur', function() {
scope.$apply(function () {
if (!elem.val() || pattern.test(elem.val())) {
ctrl.$setValidity('epost', true);
} else {
ctrl.$setValidity('epost', false);
}
});
});
ctrl.$parsers.unshift(function(viewValue) {
if (pattern.test(viewValue)) {
ctrl.$setValidity('epost', true);
return viewValue;
} else {
return undefined;
}
});
}
};
};
return Directive;
});
测试(使用jasmine和requirejs)
define([
'Angular',
'AngularMocks',
], function () {
describe('Directives', function () {
var $scope;
var form;
beforeEach(module('common'));
beforeEach(function () {
var html = '<form name="form">';
html += '<input type="text" id="epost" name="epost" epost="" ng-model="model.epost"/>';
html += '</form>';
inject(function ($compile, $rootScope) {
$scope = $rootScope.$new();
$scope.model = {
epost: null
};
// Compile the element, run digest cycle
var elem = angular.element(html);
$compile(elem)($scope);
$scope.$digest();
form = $scope.form;
});
});
describe('(epost) Given an input field hooked up with the email directive', function () {
var validEmail = 'a@b.no';
var invalidEmail = 'asdf@asdf';
it('should bind data to model and be valid when email is valid on upshift', function () {
form.epost.$setViewValue(validEmail);
expect($scope.model.epost).toBe(validEmail);
expect(form.epost.$valid).toBe(true);
});
});
});
});
答案 0 :(得分:8)
我已经能够找出断点调试后出错的地方。
我使用问题顶部描述的方法得出的“元素”项实际上并不是它自己的指令。它是一个包装表单和指令的对象。
喜欢这个
{ 0: // The form
{ 0: // The directive (input element)
{
}
}
}
为了实际模拟指令上的模糊,我做了类似的事情
var directiveElement = $(element[0][0]);
directiveElement.blur();
在获得我想要的元素并将其包装在jQuery对象(可能是可选的)之后,它就像一个魅力。然后,我使用$ setViewValue的问题中的测试方法,并像这样检查模型值。
form.epost.$setViewValue('a@b.no');
directiveElement.blur();
expect($scope.model.epost).toBe('a@b.no');
expect($scope.form.epost.$valid).toBeTruthy();
希望这对试图确定指令测试的其他人有所帮助。
答案 1 :(得分:0)
我也遇到了类似的问题,这让我感到困惑。我的解决方案是使用JQuery获取输入,然后使用angular.element(输入).triggerHandler('blur')使其工作。这对我来说很奇怪,因为我不必对click事件这样做。
spyOn(controller, 'setRevenueIsInvalid');
var sugarRow = $(element).find('tr#ve_id_5')[0];
var amount = $(sugarRow).find('input.amount')[0];
angular.element(amount).triggerHandler('blur');
expect(controller.setRevenueIsInvalid).toHaveBeenCalled();