In this short post I will show you how to unit test EventEmitters in Angular

The classic use case for EventEmitter is to trigger a custom event from a component and propagate the event up to the consumer of the component – most likely another component. It's essentially a common pattern for inter component communication.

I have created a simple example to help illustrate the scenario.

import {Component, Output, EventEmitter} from 'angular2/core'; @Component({ selector:'child', template:`<button (click)="sayHello()">Greet</button>` }) export class Child{ @Output() greeting = new EventEmitter(); sayHello(){ this.greeting.emit({greeting:'hello'}); } } @Component({ selector:'parent', template:`<child (greeting)="onGreeting($event)"></child>` }) export class Parent{ onGreeting(e){ console.log(e); } }

When the user clicks the button in the child component, a custom greeting event is dispatched. In the parent component we are trapping this event and printing the greeting to the console.

The functionality is simple enough, but how can we unit test that the greeting event actually fired? It turns out that we can take advantage of the fact that EventEmitter is an RxJs Subject in disguise. This means we can simply subscribe to EventEmitter events – directly from the test.

In the test below you will see how to wire up assertions on the expected events.

import {describe,expect,it} from 'angular2/testing'; import {Child} from './event-emitter'; export function main() { describe('Greeting Component', () => { it('should emit greeting event', (done) => { let child = new Child(); child.greeting.subscribe(g => { expect(g).toEqual({greeting:'hello'}); done(); }); child.sayHello(); }); }); }

I am using the done() parameter here, but it is strictly not necessary with the current implementation. However, I like to add it as a safeguard to guarantee that the test won't exit before the event subscription completes.