Input and outputs

So far, we have tested components in the sense that we have tested simple properties on the component and also how to tackle dependencies, synchronous as well as asynchronous, but there is more to a component than that. A component can also have input and outputs that should be tested as well. Because our context is Jedis, we know Jedis normally have ways to either the light side or the dark side. Imagine that our component is used within the context of a Jedi management system; we want to have the ability to turn a Jedi dark as well as bring it back to the light side again. What we are talking about is, of course, a toggle functionality. 

Imagine, therefore, that we have a component that looks like this:

@Component({
selector : 'jedi-detail'
template : `
<div class="jedi"
(click)="switchSide.emit(jedi)">
{{ jedi.name }} {{ jedi.side }}
</div>
`
})
export class JediComponent {
@Input() jedi:Jedi;
@Output() switchSide = new EventEmitter<Jedi>();
}

Testing such a component should be done in two ways:

  • We should verify that our input binding gets correctly set
  • We should verify that our output binding triggers properly and that what it emits is received

Starting with the @Input, a test for it would look like the following:

describe('A Jedi detail component', () => {
it('should display the jedi name Luke when input is assigned a Jedi object', () => {
const component = fixture.debugElement.componentInstance;
component.jedi = new Jedi(1, 'Luke', 'Light');
fixture.detectChanges();
expect(component.jedi.name).toBe('Luke');
});
});

Worth noting here is our call to fixture.detectChanges(), this ensures that the binding happens in the component.

Let's now have a look at how to test @Output. What we need to do is to trigger it somehow. We need to click the div defined in our template. To receive the value the switchSide property emits, we need to subscribe to it, so we need to do two things:

  • Find the div element and trigger a click on it
  • Subscribe to the emission of the data and verify that we receive our jedi object

As for getting a reference to the div, it is quite easily done, like so:

const elem = fixture.debugElement.query(By.css('.jedi'));
elem.triggerEventHandler('click', null);

For the second part, we need to subscribe to the switchSide Observable and capture the data, like so:

it('should invoke switchSide with the correct Jedi instance, () => {
let selectedJedi;
// emitting data
component.switchSide.subscribe(data => {
expect(data.name).toBe('Luke');
});
const elem = fixture.debugElement.query(By.css('.jedi'));
elem.triggerEventHandler('click', null);
})

With this code, we are able to trigger an outputs emit indirectly, through the click event and listen to the output, through a subscribe.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset