[英]Trouble unit testing Angular directive
我在弄清楚如何使用Jasmine对基本的Angular指令进行单元测试时遇到了一些麻烦。
基本上,该指令所做的就是检查两个密码输入是否相等,并设置
该指令如下所示:
angular.module('jhApp')
.directive('jhEquals', function() {
return {
restrict: 'A',
require: '?ngModel',
link: linker
};
function linker(scope, elem, attrs, ngModel) {
if(!ngModel) {
return false;
}
//watch own value and re-validate
scope.$watch(attrs.ngModel, function() {
validate();
});
//observe other value and re-validate on change
attrs.$observe('jhEquals', function() {
validate();
});
var validate = function() {
var val1 = ngModel.$viewValue;
var val2 = attrs.jhEquals;
//set validity
if(val1 && val2) {
ngModel.$setValidity('jhEquals', !val1 || !val2 || val1 === val2);
}
};
}
});
规格看起来像这样:
var scope,
dirElement;
beforeEach(function() {
module('jhApp');
module('templates');
inject(function($rootScope, $compile) {
scope = $rootScope;
scope.user = {};
dirElement = angular.element('<input id="password" type="password" name="password" ng-model="user.password" jh-equals="{{user.passwordconfirm}}"><input id="newpasswordconfirm" type="password" name="newpasswordconfirm" ng-model="user.passwordconfirm" jh-equals="{{user.password}}>');
$compile(dirElement)(scope);
});
scope.$digest();
});
it('should check if values are equal', function() {
var passwordInput = dirElement.find('#password');
var confirmPasswordInput = dirElement.find('#newpasswordconfirm');
angular.element(passwordInput).val('testpassword').trigger('input');
angular.element(confirmPasswordInput).val('nottestpassword').trigger('input');
scope.$digest();
//expect this to be invalid
});
passwordInput和ConfirmPasswordInput-在我进行console.logout时显示空对象,如果我在指令的validate()中检查val1和val2的值,则始终是未定义的。
所以我想这里的问题是我无法弄清楚如何选择要添加内容的输入。
您快要到了,但仍然存在一些小问题。
首先,您需要将指令放置在表单中以测试有效性。 还要检查最后绑定的jh-equals值是否缺少“”。
其次,jqlite find函数仅与元素选择器一起使用。 因此不可能选择dirElement.find('#testpassword')之类的元素,而是选择dirElement.find('input')。 他们之所以从jqlite中取消此功能,是为了使其更加轻巧。 相反,您可以创建dirElement.find('input')并通过索引选择所需的输入。 这似乎是一项艰巨的任务,但无论如何,大多数情况下,您都需要在jqlite中选择一个元素,该元素将位于dom树内的一小组中,例如在测试环境中或某个指令的内部厄运中。
最后,jqlite触发器称为triggerHandler,而不是触发器。
最终图片应该是这样的:
var scope, dirElement;
beforeEach(function() {
module('jhApp');
module('templates');
inject(function($rootScope, $compile) {
scope = $rootScope;
scope.user = {};
dirElement = $compile([
'<form name="form">',
'<input id="password" type="password" name="password"',
' ng-model="user.password" jh-equals="{{user.passwordconfirm}}" />',
'<input id="newpasswordconfirm" type="password"',
' name="newpasswordconfirm" ng-model="user.passwordconfirm"',
' jh-equals="{{user.password}}" />',
'</form>',
].join(''))(scope);
scope.$digest();
});
});
it('invalid if the values are not equal', function() {
var passwordInput = dirElement.find('input');
var confirmPasswordInput = dirElement.find('input')[1];
angular.element(passwordInput)
.val('testpassword')
.triggerHandler('input');
angular.element(confirmPasswordInput)
.val('nottestpassword')
.triggerHandler('input');
expect(scope.form.password.$invalid).toBe(true);
expect(scope.form.password.$valid).toBe(false);
expect(scope.form.password.$dirty).toBe(true);
expect(scope.form.newpasswordconfirm.$invalid).toBe(true);
expect(scope.form.newpasswordconfirm.$valid).toBe(false);
expect(scope.form.newpasswordconfirm.$dirty).toBe(true);
});
it('valid if the values are equal', function() {
var passwordInput = dirElement.find('input');
var confirmPasswordInput = dirElement.find('input')[1];
angular.element(passwordInput)
.val('testpassword')
.triggerHandler('input');
angular.element(confirmPasswordInput)
.val('testpassword')
.triggerHandler('input');
expect(scope.form.password.$invalid).toBe(false);
expect(scope.form.password.$valid).toBe(true);
expect(scope.form.password.$dirty).toBe(true);
expect(scope.form.newpasswordconfirm.$invalid).toBe(false);
expect(scope.form.newpasswordconfirm.$valid).toBe(true);
expect(scope.form.newpasswordconfirm.$dirty).toBe(true);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.