如何在输入字段中测试对键击事件有反应的指令

时间:2019-08-07 13:11:14

标签: angular unit-testing angular7

我通过检查按下了哪个按钮,编写了一个防止Keyboarddefaults的指令。我正在尝试对指令进行单元测试。我可以看到该指令在应用程序中运行,或者在我将console.log()放入指令中时看到。不起作用的是键入的字母不会设置到组件ngModelField中。

我已经尝试了很多东西,包括夹具.detectChanges(),夹具.whenStable()等。

我的指令:

private allowed  = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',]

@HostListener('keydown', ['$event'])
  onKeyDown(e: KeyboardEvent) {
    if (this.allowed.indexOf(e.key) > -1) {
      console.log('allowed');
      return;
    }
    console.log('preventdefault');
    e.preventDefault();
  }

我的单元测试:

describe('OnlyDecimalDirective', () => {
  let fixture: ComponentFixture<MockOnlyDecimalComponent>;
  let component: MockOnlyDecimalComponent;
  let input: HTMLInputElement;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [OnlyDecimalDirective, MockOnlyDecimalComponent],
      imports: [FormsModule],
    });
    fixture = TestBed.createComponent(MockOnlyDecimalComponent);
    component = fixture.componentInstance;
    input = fixture.debugElement.query(By.css('input')).nativeElement;
  }));

  it('sollte Ziffern akzeptieren', () => {
    fixture.detectChanges();
    let keyDown = new KeyboardEvent('keydown', { key: '5' });
    input.dispatchEvent(keyDown);
    console.log(component.text)
  });

});

我的单元测试的MockComponent

@Component({ template: '<input onlyDecimal [(ngModel)]="text" type="string">' })
export class MockOnlyDecimalComponent {
  public text = '';
}

我需要测试结果。因此,我希望如果触发Keydown事件,则component.text字段将获取我在新KeyBoardEvent中发布的键的值:

let keyDown = new KeyboardEvent('keydown', { key: '5' }); // key: 's' should prevent default

我可以看到console.log()出现了,但是我无法测试最终结果,因为我不会在component.text中显示

有人要求我进行Stackblitz: https://stackblitz.com/edit/angular-testing-callback-cuqg9m

1 个答案:

答案 0 :(得分:1)

input.dispatchEvent(keyDown);
console.log(component.text);

在DOM元素上调用dispatchEvent()不会更新输入文本。使用手动DOM事件,您不能非常轻松地模拟用户交互。模拟键盘输入所涉及的DOM事件比keydown事件要多得多。当用户在键盘上键入内容时,将发生诸如更改事件,焦点事件和多个键盘事件之类的事情。

例如,如果用户从剪贴板粘贴文本或使用浏览器的自动完成功能,则您的指令不起作用。

如果您想限制表单的值,则需要构建一个自定义模板驱动器验证器来更改输入值。

https://angular.io/guide/form-validation#custom-validators