在使用 karma 的角度单元测试中 dispatchEvent() 和 triggerEventHandler() 有什么区别?

Ana*_*han 6 jasmine angular

我正在为指令(在输入事件上调用)编写单元测试,该指令正在修改 formControl 上的输入值。我在我的规范文件中为此创建了一个测试组件。我注意到 triggerEventHandler() 和 dispatchEvent() 之间的区别,当 dispatchEvent() 正确触发事件并触发指令时,在 triggerEventHandler() 事件未触发的情况下。谁能告诉我,除了在 nativeElement 上调用 dispatchEvent() 之外,它们之间有什么区别。

// directive
export class AlphaNumericCheckDirective {

  constructor(private ctrl: NgControl) {
  }
  @HostListener('input')
  onInputChange() {
    const pattern = /[^0-9]/g;
    const elVal = (this.ctrl.control as AbstractControl).value;
    if (pattern.test(elVal)) {
      const newVal = elVal.replace(pattern, '');
      (this.ctrl.control as AbstractControl).setValue(newVal);
    }
  }
}

// relevant code of test
it('should allow only numerics', () => {
   const fixture = TestBed.createComponent(TestComponent);
   const inputEl = fixture.debugElement.query(By.css('input'));
   (fixture.componentInstance.testGroup.get('testControl') as 
   AbstractControl).patchValue('12a');
   inputEl.triggerEventHandler('input', null); // not triggering the directive
   inputEl.nativeElement.dispatchEvent(new Event('input')); // triggering the directive
});
Run Code Online (Sandbox Code Playgroud)

Pri*_*hra 7

triggerEventHandler属于角度。triggerEventHandler仅当使用Angular event bindings、 the@HostListener()或装饰器在本机元素上声明事件处理程序时,才会调用该事件处理程序@Output

\n\n

dispatchEvvent当我们通过 定义事件时会派上用场JS native APIs,例如。RxJSfromEvent可观察等

\n\n

我们甚至可以dispatchEvent在测试时用来模拟 Angular Material 组件的事件,但triggerEventHandler由于 Angular 不知道这些事件,因此在那里不起作用。

\n\n

这是一篇非常有趣的文章,将帮助您清楚地理解差异https://netbasal.com/simulated-events-in-angular-unit-tests-5482618cd6c6

\n

  • 我已阅读这篇文章,我知道其中的区别,但我认为使用 `triggerEventHandler` 没有任何优势,它更冗长,您需要自己调用更改检测。同时 `dispatchEvent` 可以处理所有事情。 (2认同)

Tim*_*Tim 0

我也注意到同样的问题。我发现triggerEventHandler()适用于按钮测试场景,但不适用于输入情况,而dispatchevent适用于输入场景(即您的情况)。