在angularjs测试中对paste和keypress事件使用element.triggerHandler()似乎没有效果

时间:2016-11-30 18:46:20

标签: javascript angularjs jqlite

想知道是否有人可以了解如何在angularjs单元测试中正确使用element.triggerHandler()paste事件。

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

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

对于keypress测试,我知道我没有使用正确的语法,但一直无法找到如何正确执行此操作。有什么建议吗?

paste

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

一直坚持这一点,任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:0)

让我们从用户按下并释放1键并重点关注输入时可能发生的事情(真正取决于浏览器实现)的简短细分开始:< / p>

  1. 事件keydown被解雇
  2. 事件keypress被解雇
  3. 输入值更改为1并触发事件input
  4. 事件keyup被解雇
  5. 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');
    

    但这不起作用,因为即使第11个按键事件被指令捕获,下面的代码仍将执行并更新该值。

    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://github.com/php/php-src/blob/9bcd2bcc21b7739a03acbe4e86dea1efef98c7fd/main/main.c#L299

    现在,您可以轻松地测试元素值何时设置为等于/低于允许值。

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