Angular How to test @HostListener
10,160
I found a solution. Instead of checking for value (which never changes), I just check the defaultPrevented property on the event.
I was also missing two things :
fixture.detectChanges(); in the beforeEach
event should be cancelable
Here's the full test :
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 { }
});
Comments
-
Sam about 2 years
I have the following directive. When applied to an input element, it checks for characters and calls preventDefault when the character is forbidden:
@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(); } }
Works fine, but I can't figure out how to test it. I have the following so far:
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 { } });
It's not working though. The keypress event is not triggered. Any idea how to test this directive ?