Reputation: 693
I created an directive to allow only numbers for a input field and I want to cover this directive with unit test. But I don't know how to cover the @HostListener('input') onChange()
part of my code.
The directive:
import { Directive, ElementRef, Input, HostListener, Renderer2 } from '@angular/core';
@Directive({
selector: '[onlyNumbers]'
})
export class OnlyNumbersDirective {
@Input() onlyNumbers: boolean | undefined;
constructor(private el: ElementRef, private renderer2: Renderer2) {
}
@HostListener('input') onChange() {
if(this.onlyNumbers) {
const { value } = this.el.nativeElement;
this.renderer2.setProperty(this.el.nativeElement, 'value', value.replace(/[^0-9]/g, ''));
}
}
}
Unit test which I tried:
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { OnlyNumbersDirective } from './onlyNumbers.directive';
import { Component, Input, OnInit} from '@angular/core';
// Create component to test
@Component({
template: `<input type="text" [ngModel]="value" [onlyNumbers]="enableNumbers"/>`
})
class TestComponent implements OnInit {
@Input() enableNumbers = true;
@Input() value : any;
ngOnInit() {
this.enableNumbers = true;
this.value = '123a'
}
}
describe('OnlyNumbersDirective', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
TestComponent,
OnlyNumbersDirective
]
});
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
});
it('should create component', () => {
expect(component).toBeDefined();
});
it('should allow numbers only', () => {
const debugEl: HTMLElement = fixture.debugElement.nativeElement;
const input: HTMLElement = debugEl.querySelector('input');
fixture.detectChanges();
expect(input.value).toBe('123');
});
});
How can I cover the @HostListener('input') onChange()
part with Jasmine/Karma in Angular?
Upvotes: 1
Views: 4035
Reputation: 693
Fixed by creating a component inside the unit test and by using the directive directly with this created component.
it('should allow numbers only', () => {
const event = new Event('input', {} as any);
const component = TestBed.createComponent(NameComponent);
input = component.debugElement.query(By.directive(NameDirective));
component.detectChanges();
input.nativeElement.value = '1a';
input.nativeElement.dispatchEvent(event);
expect(input.nativeElement.value).toBe('1');
});
Upvotes: 2
Reputation: 18849
Try something like this:
it('should do xyz', () => {
const input = fixture.debugElement.nativeElement.querySelector('input');
input.dispatchEvent(new Event('change', {target: {value: 'value of input goes here'}} as any)); // try adding as any here
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(1).toBe(1); // dummy assertion here but you can put your assertions here.
});
});
Upvotes: 0