2014-01-18 50 views
6

我正在嘗試測試我正在寫入的新指令。但是,我似乎無法獲得在Karma/Jasmine中使用jQuery觸發的keydown事件。AngularJS中的jQuery觸發器事件Karma測試

下面是測試的簡化版本:

'use strict'; 

describe('', function() { 

    var $compile; 
    var $scope; 

    beforeEach(inject(function(_$compile_, _$rootScope_) { 
    $compile = _$compile_; 
    $scope = _$rootScope_.$new(); 
    })); 

    describe('Getting Trigger To Work', function() { 

    it('Should Trigger a KeyDown Event', function() { 

     var el = $compile('<form name="testing"><input id="field1" name="testfield" ng-model="result" type="text" ng-minlength="5" ng-maxlength="50"/></form>')($scope); 
     console.log(el); 

     var inputEl = el.find('input'); 
     console.log(inputEl); 

     var e = $.Event('keydown'); 
     e.which = 65; 

     inputEl.trigger(e); 

    }); 

    }); 

}); 

我的人緣配置包括AngularJS和jQuery。下面是部分:

// 
files: [ 
    'lib/angular.js', 
    'lib/angular-mocks.js', 
    'lib/jquery-1.10.2.min.js', 
    'test/**/*Spec.js' 
], 

當我運行測試,我得到我的輸入元素沒有觸發方法的錯誤:

INFO [watcher]: Changed file "/Volumes/Macintosh HD/dev_libraries/val-on-timeout/test/valOnTimeoutSpec.js". 
LOG: Object{0: <form name="testing" class="ng-scope ng-pristine ng-valid"><input id="field1" name="testfield" ng-model="result" type="text" ng-minlength="5" ng-maxlength="50" class="ng-pristine ng-valid"></form>, length: 1} 
LOG: Object{0: <input id="field1" name="testfield" ng-model="result" type="text" ng-minlength="5" ng-maxlength="50" class="ng-pristine ng-valid">, length: 1} 
Chrome 32.0.1700 (Mac OS X 10.8.5) testing valOnTimeout Should load FAILED 
    TypeError: Object [object Object] has no method 'trigger' 
     at null.<anonymous> (/Volumes/Macintosh HD/dev_libraries/val-on-timeout/test/valOnTimeoutSpec.js:79:21) 
Chrome 32.0.1700 (Mac OS X 10.8.5): Executed 1 of 1 (1 FAILED) ERROR (0.327 secs/0.033 secs) 

起初,你可能會認爲jQuery是不包括在內。但是,它包含在內。如果不是,測試將失敗,在$.Event

關於讓keydown事件處理輸入的建議?

+0

這就是問題所在。 '[object Object]沒有方法'trigger''所以我不能觸發任何事件。 – Justin

+0

對不起,我的意思是'angular.element(inputEl).trigger('keydown')' – dcodesmith

+0

@dcodesmith謝謝。試過。沒有運氣。仍然'對象[對象對象]沒有方法'trigger'' – Justin

回答

11

我希望這個作品

var e = $.Event('keydown'); 
    e.which = 65; 

    $(inputEl).trigger(e); // convert inputEl into a jQuery object first 
    // OR 
    angular.element(inputEl).triggerHandler(e); // angular.element uses triggerHandler instead of trigger to trigger events 
+0

我通過Twitter得到了另一個相同的答案,但你在這裏得到了投票。 '$(inputEl).trigger(e)'做了訣竅。謝謝 – Justin

2

TLDR:AngularJS之前加載jQuery的。

起初,你可能會認爲jQuery不包括在內。但是,它包括 。如果不是,測試將失敗$ .Event。

您對jQuery的2只依賴這裏:

  1. $.Event,直接引用;和
  2. $,間接由angular.element()引用;

當AngularJS被加載時,它會尋找以前加載jQuery的實例,並且如果它確實存在,它使element只是一個別名$。否則,它將加載對jqLit​​e的引用,該引用沒有trigger方法。

所以,我相信你有jQuery加載,但這並不意味着AngularJS會使用它。爲此,你必須確保jQuery在AngularJS之前被加載(任何地方)。

angular.element()引用jqLit​​e時,即使加載jQuery後,也不會調用jQuery。所以,你只能叫上jqLit​​e定義的方法:

angular.element(inputEl).triggerHandler(e); 

然而,jqLit​​e的triggerHandler不會執行事件冒泡,這是不可靠的嘲笑引發事件。 jQuery的trigger更好。

使用jQuery,做你的HTML:

<script src="jquery.js"> 
<script src="angular.js"> 

或在您karma.conf。JS:

files: [ 
    'lib/jquery-1.10.2.min.js', 
    'lib/angular.js', 
    'lib/angular-mocks.js', 
    'test/**/*Spec.js' 
], 

參考:

建議上得到keydown事件對輸入工作?

您已經找到了解決此問題的一種方法。這對你的單元測試並不是什麼大問題,在那裏你會想要一個更好的DOM庫,但是現在你知道發生了什麼。 PS:我真的很喜歡回答這個問題。從一年多的問題來看,6k用戶看來,仍然沒有回答核心的問題。