【问题标题】:How do I trigger a keyup/keydown event in an angularjs unit test?如何在 angularjs 单元测试中触发 keyup/keydown 事件?
【发布时间】:2013-08-02 19:06:10
【问题描述】:

我想对模拟占位符的指令进行单元测试,其中输入值仅在 keyup/down 事件时被清除。

【问题讨论】:

    标签: unit-testing angularjs jasmine


    【解决方案1】:

    您需要以编程方式创建事件并触发它。这样做包括用于单元测试的 jQuery 是非常有用的。例如,您可以编写一个像这样的简单实用程序:

      var triggerKeyDown = function (element, keyCode) {
        var e = $.Event("keydown");
        e.which = keyCode;
        element.trigger(e);
      };
    

    然后像这样在单元测试中使用它:

    triggerKeyDown(element, 13);
    

    您可以在http://angular-ui.github.io/bootstrap/ 项目中看到这种技术的实际应用:https://github.com/angular-ui/bootstrap/blob/master/src/typeahead/test/typeahead.spec.js

    免责声明:让我们在这里准确地说:我不提倡使用 jQuery 和 AngularJS!我只是说它是一个有用的 DOM 操作实用程序,用于编写与 DOM 交互的测试。

    要使上述代码在没有 jQuery 的情况下工作,请更改:

    $.Event('keydown')
    

    到:

    angular.element.Event('keydown')
    

    【讨论】:

    • 缺点是 jQuery 很容易替换 Angular 自带的 jQueryLite。由于存在实际的功能差异,因此您实际上是在通过将其包含在单元测试中来测试(稍微)不同的系统。
    • angular.element.Event 是否仍然可用?我越来越不确定,我在文档中看不到任何关于它的内容。 docs.angularjs.org/api/ng/function/angular.element
    【解决方案2】:

    我在使用接受的答案时遇到了问题。我找到了其他灵魂。

    var e = new window.KeyboardEvent('keydown', {
      bubbles: true,
      cancelable: true,
      shiftKey: true
    });
    
    delete e.keyCode;
    Object.defineProperty(e, 'keyCode', {'value': 27});
    
    $document[0].dispatchEvent(e);
    

    可以在here找到工作示例

    【讨论】:

    • 我使用了这种方法,所以 +1 但它似乎在 PhantomJS 中不起作用。
    • 我在我的 karma 配置中使用 Chrome,因为 PhantomJS 不支持 bind
    【解决方案3】:

    我得到了这样的工作。

    element.triggerHandler({type:"keydown", which:keyCode});
    

    【讨论】:

    • 也适合我
    • triggerHandler 不是函数,Agular 8。
    【解决方案4】:

    如果您使用 angular2,您可以通过在 HTMLElement 实例上调用 dispatchEvent(new Event('mousedown')) 来触发任何事件。例如:使用 angular 2.rc1 测试

    it('should ...', async(inject([TestComponentBuilder], (tcb:TestComponentBuilder) => {
    return tcb.createAsync(TestComponent).then((fixture: ComponentFixture<any>) => {
      fixture.detectChanges();
    
      let com = fixture.componentInstance;
    
      /* query your component to select element*/
      let div:HTMLElement = fixture.nativeElement.querySelector('div');
    
     /* If you want to test @output you can subscribe to its event*/
      com.resizeTest.subscribe((x:any)=>{
        expect(x).toBe('someValue');
      });
      /* If you want to test some component internal you can register an event listener*/
      div.addEventListener('click',(x)=>{
        expect(x).toBe('someOtherValue');
      });
      /* if you want to trigger an event on selected HTMLElement*/
      div.dispatchEvent(new Event('mousedown'));
      /* For click events you can use this short form*/
      div.click();
    
      fixture.detectChanges();
    });
    

    【讨论】:

    • 这如何回答这个问题?如何使用 dispatchEvent 触发 keyup/keydown 事件?新事件('keydown.esc')不起作用
    【解决方案5】:

    我最近想在一个组件(Angular 2)上测试这个 HostListener:

      @HostListener('keydown.esc') onEsc() {
        this.componentCloseFn();
      };
    

    搜索了一段时间后,这是有效的:

    ..
    nativeElement.dispatchEvent(new KeyboardEvent('keydown', {'key': 'Escape'}));
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-17
      • 1970-01-01
      • 2011-03-23
      • 2012-02-08
      • 1970-01-01
      • 2016-09-21
      • 1970-01-01
      相关资源
      最近更新 更多