在 angularjs 测试粘贴和按键事件中使用 element.triggerHandler() 似乎没有效果

Using element.triggerHandler() in angularjs tests for paste and keypress events doesn't seem to have an effect

想知道是否有人可以阐明如何在 angularjs 单元测试中为 pastekeypress 事件正确使用 element.triggerHandler()

我有两个指令,一个用于限制用户在达到长度限制后继续触发元素中的 keypress 事件的能力。第二个是防止用户在文本长度超过限制时将文本粘贴到元素中。

请参阅以下 plunker 以获取包含我失败测试的完整示例:https://plnkr.co/edit/5Yyv2cnn3dRKzsj2Lj61?p=preview

对于 paste 测试,我知道我没有使用正确的语法,但一直无法找到正确的方法。有什么建议吗?

element.triggerHandler('paste', 'astring')

对于 keypress 测试,我相信我正确地触发了事件,但它似乎没有更新元素的值(使用 element.val() 检索)

在此问题上停留了一段时间,如有任何帮助,我们将不胜感激。谢谢!

让我们首先简要分析当用户按下并释放带有焦点的 1 键时可能发生的情况(真正取决于浏览器实现)输入:

  1. 事件 keydown 已触发
  2. 事件 keypress 已触发
  3. 输入值更改为 1 并触发事件 input
  4. 事件 keyup 已触发

JS 没有办法真正模拟用户按下一个键。您可以模拟的是用户这样做时(通常)发生的事情,例如上面的步骤。

triggerHandler 函数为特定元素上的指定事件类型执行与 jQuery 绑定的所有处理程序。

所以使用 triggerHandlerkeypress 不会模拟用户按下一个键,它只会触发事件,就像上面的第 2 步一样。该值不会更改,因为那是在另一步中发生的。

现在,有人会认为在 limitKeypressLength 指令的测试中,您可以自己简单地模拟上面步骤 3 的第一部分(只需手动设置值):

for (var i = 0; i < 10; i++) {  
  element.triggerHandler({type: 'keypress', keyCode: 49});
  element.val(element.val() + '1');
}

expect(element.val()).toBe('1111111111');

element.triggerHandler('keypress', {which: 49});
element.val(element.val() + '1');

expect(element.val()).toBe('1111111111');

但这不会起作用,因为即使在您的指令中捕获了第十一个按键事件,下面的代码仍会执行并更新值。

limitKeypressLength 指令的基本功能是监听按键事件并调用 event.preventDefault 或不基于。这就是你要测试的。

例如:

// Set value to something longer than allowed
element.val('123456789123456789');

// Create the event
var e = jQuery.Event('keypress', {
  keyCode: 49
});

// Create a spy
spyOn(e, 'preventDefault');

// preventDefault should not have been called yet
expect(e.preventDefault).not.toHaveBeenCalled();

// Trigger the event
element.triggerHandler(e);

// Assert that preventDefault has been called
expect(e.preventDefault).toHaveBeenCalled();

演示: https://plnkr.co/edit/ktmcBGSuTdMnvqVRlkeQ?p=preview

现在您可以轻松测试何时将元素值设置为 equal/below 允许值。

limitPasteLength 指令基本上也是如此,因为它的目的也是根据条件调用 preventDefault,只是需要做一些额外的模拟。