javascript - Evento de activación de jQuery en AngularJS Karma Test
jasmine karma-runner (2)
Estoy tratando de probar una nueva directiva que estoy escribiendo. Sin embargo, parece que no puedo obtener el evento keydown para desencadenar con jQuery dentro de Karma / Jasmine.
Aquí hay una versión simplificada de la prueba:
''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);
});
});
});
Mi configuración de karma incluye AngularJS y jQuery. Aquí está esa sección:
//
files: [
''lib/angular.js'',
''lib/angular-mocks.js'',
''lib/jquery-1.10.2.min.js'',
''test/**/*Spec.js''
],
Cuando ejecuto la prueba, aparece un error que indica que mi elemento de entrada no tiene un método de activación:
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)
Al principio, puede pensar que jQuery no está incluido. Sin embargo, está incluido. Si no fuera así, la prueba fallaría en $.Event
.
¿Sugerencias para que el evento de selección funcione en la entrada?
espero que esto funcione
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
TLDR : carga jQuery antes de AngularJS.
Al principio, puede pensar que jQuery no está incluido. Sin embargo, está incluido. Si no fuera así, la prueba fallaría en $ .Event.
Tienes 2 dependencias en jQuery aquí:
-
$.Event
, una referencia directa; y -
$
, indirectamente referenciado porangular.element()
;
Cuando se carga AngularJS, busca una instancia de jQuery previamente cargada, y en caso de que exista, hace que el element
sea solo un alias de $
. De lo contrario, carga una referencia a jqLite, que no tiene un método de trigger
.
Entonces, estoy seguro de que tienes jQuery cargado, pero eso no significa que AngularJS lo usará. Para hacerlo, debe asegurarse de que jQuery esté cargado (en cualquier lugar) antes de AngularJS.
Cuando angular.element()
refiere a jqLite, nunca llamará a jQuery, incluso después de que se cargue jQuery. Entonces solo puedes llamar a los métodos definidos en jqLite:
angular.element(inputEl).triggerHandler(e);
Sin embargo, el triggerHandler de triggerHandler
no realizaría el burbujeo del evento, no es confiable simular eventos. El trigger
de jQuery es mucho mejor.
Para usar jQuery, haz esto en tu HTML:
<script src="jquery.js">
<script src="angular.js">
O en tu karma.conf.js:
files: [
''lib/jquery-1.10.2.min.js'',
''lib/angular.js'',
''lib/angular-mocks.js'',
''test/**/*Spec.js''
],
Referencia:
- https://docs.angularjs.org/api/ng/function/angular.element
- https://github.com/angular/angular.js/blob/master/src/Angular.js#L1608
¿Sugerencias para que el evento de selección funcione en la entrada?
Has encontrado un enfoque al solucionar el problema. No es un gran problema para tus pruebas unitarias , donde querrías una mejor biblioteca DOM, pero ahora sabes lo que está pasando.
PD: Me gustó mucho responder a esto. Una pregunta de más de un año, vista por 6k usuarios, y aún sin respuesta al problema central .