Angular: Unit Test: trigger events in tests

peng37
2 min readApr 8, 2019

--

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;
}
}
  1. 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 = value
inputEl.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');
});

--

--