Angular Как протестировать @HostListener

У меня есть следующая директива. При применении к элементу ввода он проверяет наличие символов и вызывает preventDefault, когда символ запрещен:

@Directive({
 selector: '[cdtPreventInput]'
})
  export class PreventInputDirective implements OnInit {

  // the list of characters that are to be prevented
  @Input() cdtPreventInput: String;

  constructor() { }

  ngOnInit() {
    if (!this.cdtPreventInput) {
      throw new Error('cdtPreventInput cannot be used without providing a 
          list of characters.');
    }
  }

 @HostListener('keypress', ['$event']) onKeyPress(event) {
   if (_.includes(this.cdtPreventInput.split(','), event.key)) {
    event.preventDefault();
  }
}

Работает нормально, но я не могу понять, как это проверить. У меня пока следующее:

describe('PreventInputDirective', () => {
  let fixture;
  let input: DebugElement;

  beforeEach(() => {
    fixture = TestBed.configureTestingModule({
      declarations: [PreventInputDirective, TestComponent]
    }).createComponent(TestComponent);

    input = fixture.debugElement.query(By.directive(PreventInputDirective));
  });

  it('should create an instance', () => {
    const directive = new PreventInputDirective();
    expect(directive).toBeTruthy();
  });

 it('should prevent default keypress event', () => {
    const event = new KeyboardEvent('keypress', {
      'key': '.'
    });
     input.nativeElement.dispatchEvent(event);

     expect(input.nativeElement.value).toEqual('');
  });

  @Component({
    template: `<input cdtPreventInput="." />`
  })
  class TestComponent { }
});

Однако это не работает. Событие нажатия клавиши не срабатывает. Любая идея, как проверить эту директиву?


person Sam    schedule 22.02.2018    source источник


Ответы (1)


Я нашел решение. Вместо проверки значения (которое никогда не меняется) я просто проверяю свойство defaultPrevented события.

Мне тоже не хватало двух вещей:

  • приспособление.detectChanges(); в докаждом

  • событие должно быть отменено

Вот полный тест:

     describe('PreventInputDirective', () => {
      let fixture;
      let input: DebugElement;
    
      beforeEach(() => {
        fixture = TestBed.configureTestingModule({
          declarations: [PreventInputDirective, TestComponent]
        }).createComponent(TestComponent);
    
        input = fixture.debugElement.query(By.directive(PreventInputDirective));
        fixture.detectChanges();
      });
    
      it('should create an instance', () => {
        const directive = new PreventInputDirective();
        expect(directive).toBeTruthy();
      });
    
      it('should prevent keypress event', () => {
        const event = new KeyboardEvent('keypress', {
          'key': '.',
          cancelable: true
        });
    
        input.nativeElement.dispatchEvent(event);
        expect(event.defaultPrevented).toBeTruthy();
      });
    
      it('should not prevent keypress event', () => {
        const event = new KeyboardEvent('keypress', {
          'key': '5',
          cancelable: true
        });
    
        input.nativeElement.dispatchEvent(event);
        expect(event.defaultPrevented).toBeFalsy();
      });
    
      @Component({
        template: `<input cdtPreventInput="." />`
      })
      class TestComponent { }
    });
person Sam    schedule 23.02.2018