When I test Angular components, I am mainly testing the component template logic.
If some content should be shown, then I will test if the content is there;
If some events should be triggered, and some tasks should be executed, then I will test the event and its results.
In this post I will show, how to trigger events in unit tests.
—
Check code here.
—
This is the component I want to test:
A child component:
@Component({
selector: 'mst-trigger-child',
template: '<button (click)="clickButton()">child component</button>',
})
export class TriggerChildComponent {
@Output() newNumber = new EventEmitter<number>(); private count = 0; clickButton() {
this.count = this.count + 1;
this.newNumber.emit(this.count);
}
}
A parent component:
@Component({
selector: 'mst-trigger-parent',
templateUrl: `
<div>
<div>click event:</div>
<button (click)="clickButton()">click me</button>
<span class="mst-click-count">{{ clickCount }}</span>
</div> <div>
<div>input event:</div>
<input type="text" [formControl]="formControl (focus)="focusInput()"/>
<div class="mst-focus-count">focus count: {{ focusCount }}</div>
<div class="mst-input-value">input value: {{ inputValue }}</div>
</div> <div>
<div>child component event:</div>
<mst-trigger-child (newNumber)="handleNewNumber($event)"></mst-trigger-child>
<div class="mst-child-count">child count: {{ childCount }}</div>
</div>
`,
})
export class TriggerParentComponent implements OnInit, OnDestroy {
clickCount = 0;
focusCount = 0;
inputValue = '';
childCount = 0; formControl = new FormControl();
private valueChangeSub: Subscription; ngOnInit() {
this.valueChangeSub = this.formControl.valueChanges.subscribe((value) => {
this.inputValue = value;
}); }
ngOnDestroy() {
this.valueChangeSub.unsubscribe();
}
clickButton() {
this.clickCount = this.clickCount + 1;
}
focusInput() {
this.focusCount = this.focusCount + 1;
}
handleNewNumber(num: number) {
this.childCount = num;
}
}
- Trigger “click” event.
Just call the “click” method of the DOM element.
it('should click once', () => {
fixture.detectChanges();
queryDebugElement(de, 'button').nativeElement.click();
fixture.detectChanges(); hasContent(queryDebugElement(de, '.mst-click-count'), '1');
});
2. Trigger “focus” event.
You can use the “triggerEventHandler” on DebugElement.
it('should focus once', () => {
fixture.detectChanges();
queryDebugElement(de, 'input').triggerEventHandler('focus', null);
fixture.detectChanges(); hasContent(queryDebugElement(de, '.mst-focus-count'), '1');
});
3. Trigger “input” event.
You can firstly set the value of the DOM input value, then use “triggerEventHandler”.
it('should has input value', () => {
fixture.detectChanges();
const inputEl = queryDebugElement(de, 'input');
const value = 'trigger input event';
inputEl.nativeElement.value = valueinputEl.triggerEventHandler('input', { target: inputEl.nativeElement });
fixture.detectChanges(); hasContent(queryDebugElement(de, '.mst-input-value'), value);
});
4. Trigger child component event.
You can firstly query the child components, then emit a new value.
it('should handle child event', () => {
fixture.detectChanges();
const childEl: TriggerChildComponent = de.query(By.directive(TriggerChildComponent)).componentInstance;
childEl.newNumber.emit(3)
fixture.detectChanges();
hasContent(queryDebugElement(de, '.mst-child-count'), '3');
});