[英]Karma unit test angular directives with key event handler
幾個星期前,我進入了JavaScript的世界。 我使用Angular,然后用Karma和Jasmine測試我的代碼。 我有一個角度指令,我在測試時遇到了麻煩。
我有一個角度指令,意味着與<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元素中提取我的事件處理函數,並對函數進行單元測試。 到目前為止沒有工作。
我該如何最好地測試我的角度指令?
在測試中,您可以實際注入指令定義對象(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);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.