我正试图在链接上测试点击'preventDefault'被调用。但是,我很难用一个可以监视的实际“事件”对象替换:
以下是触发点击事件的方法:
var e = jasmine.createSpyObj('e', [ 'preventDefault' ]);
$element.triggerHandler('click', [e]);
但是,当运行指令代码时,事件元素不会被伪造的代替:
$element.on('click', function(event) {
console.log(event);
}
我尝试了不同的方法向triggerHandler添加第二个参数 - 作为一个数组,作为一个对象,只是一些行等。都没有工作..它也不是很多triggerHandler的例子和其他参数,所以我觉得有点失落......
提前致谢!
答案 0 :(得分:27)
当我们想要传递一个具有triggerHandler
属性特定值的测试事件时,我们也遇到了这个问题。
正如c0bra所指出的,triggerHandler
函数创建了自己的虚拟事件对象,然后将其传递给事件处理程序。但是,如果事件中存在值type
属性,则可以利用triggerHandler: function(element, event, extraParameters) {
...
// If a custom event was provided then extend our dummy event with it
if (event.type) {
dummyEvent = extend(dummyEvent, event);
}
...
}
函数扩展虚拟事件并传入事件对象这一事实:
https://github.com/angular/angular.js/blob/v1.6.5/src/jqLite.js#L1043
element.triggerHandler
在检查Angular代码后,我们发现当您从测试中调用triggerHandler
时,它将首先调用一个匿名函数,然后调用Angular的{{1}功能。当调用Angular的triggerHandler
函数时,它将元素作为第一个参数传递,然后传递给测试中作为第二个参数的triggerHandler
的第一个参数,然后是第二个参数您传递给triggerHandler
作为第三个等https://github.com/angular/angular.js/blob/v1.6.5/src/jqLite.js#L1068
这意味着您可以将测试中的对象作为第一个参数传递给triggerHandler
,并且该对象的属性将被附加到虚拟事件对象(如果已经存在,则会被覆盖虚拟对象上具有相同名称的属性),从而允许您传递特定值并添加间谍以进行测试。
请注意,事件类型需要作为对象的type属性传递给triggerHandler
,以满足上面提到的if条件。例如,这就是我们在测试中使用triggerHandler
的方式:
element.triggerHandler({
type: 'keydown',
which: 13
});
答案 1 :(得分:2)
文档说triggerHandler()
将虚拟对象传递给处理程序:http://docs.angularjs.org/api/ng/function/angular.element
如果检查源代码,可以看到triggerHandler()
创建了自己的事件对象,然后将第二个参数作为事件数据传递,而不是实际的事件对象:
https://github.com/angular/angular.js/blob/master/src/jqLite.js#L882
相关代码:
var event = [{
preventDefault: noop,
stopPropagation: noop
}];
forEach(eventFns, function(fn) {
fn.apply(element, event.concat(eventData));
});
我使用jQuery的内部事件模拟器来创建自己的事件。这可能适合您:http://wingkaiwan.com/2012/09/23/triggering-mouse-events-with-jquery-simulate-when-testing-in-javascript/