我有一个与<input>
框一起使用的角度指令。该指令修改输入框,因此它只接受数字作为输入。这是代码的简化版本:
var testDirective = angular.module('testDirectiveApp', []);
testDirective.directive('numberOnly', function() {
return {
restrict: 'A',
link: function (scope, element) {
element.on('keydown', function (event) {
var k = event.keyCode;
if (48 <= k && k <= 57) {
return true;
}
event.preventDefault();
return false;
});
}
};
});
我会在html中使用它:
<div>
Numbers only: <input number-only ng-required="true"
ng-model="myNumber" type="text" maxlength="3"
placeholder="NNN">
</div>
我想测试该指令是否正确连接,并成功过滤掉非数字输入。如果我输入“a1b2c3”,输入框应该为“123”。
我尝试了很多不同的方法将字符串输入到输入框并检查一个值(输入框,角度模型等),但是到目前为止它们都没有。
以下测试是我许多试验的一个例子:
describe('numberOnly', function() {
'use strict';
var scope, element;
beforeEach(module('testDirectiveApp'));
beforeEach(inject(function($compile, $rootScope) {
scope = $rootScope.$new();
scope.testInput = "";
element = angular.element('<input number-only ng-model="testInput" type="text">');
$compile(element)(scope);
scope.$digest();
}));
it('should accept number input', function() {
triggerKeyDown(element, 49);
expect(scope.testInput).toBe("1");
});
var triggerKeyDown = function (element, keyCode) {
var e = $.Event("keydown");
e.which = keyCode;
e.keyCode = keyCode;
$(element).trigger(e);
};
});
我甚至尝试编写e2e测试来模拟用户输入。我也尝试从HTML元素中提取我的事件处理函数,并对函数进行单元测试。到目前为止没有工作。
我应该如何最好地测试我的角度指令?
答案 0 :(得分:0)
在测试中,您可以实际注入指令定义对象(DDO),然后直接调用链接函数,而无需实际创建元素。
Angular允许添加具有相同名称但具有不同优先级的指令。 Angular以数组的形式创建指令的注入(因为有多个优先级事物)。假设您只声明了一次指令,我们可以假设您的DDO是数组中的第一个。
此代码未经测试,但应该可以帮助您完成任务。
describe('numberOnly', function() {
var scope, linkFunction;
beforeEach(module('testDirectiveApp'));
beforeEach(inject(function($compile, $rootScope, numberOnlyDirective) {
scope = $rootScope.$new();
//get the link function
linkFunction = numberOnlyDirective[0].link;
});
it('calls the event', function(){
//make a mock element that has the 'on' function.
var onCallback;
var mockElement = {
on: function(eventName, cb){
expect(eventName).toEqual("keydown");
//save the callback so we can call it in our test
onCallback = cb;
}
};
linkFunction(scope, mockElement);
var preventDefaultWasCalled = false;
var mockEvent = {
which: 1,
keyCode: 1,
preventDefault: function(){
preventDefaultWasCalled = true;
}
};
//trigger the 'keydown' event by calling the callback
onCallback(mockEvent);
expect(preventDefaultWasCalled).toEqual(true);
});