With Host

Last updated 6 months ago

Testing a component with a host is a more elegant and powerful technique to test your component. It basically gives you the ability to write your tests in the same way that you write your code. Let's see it in action:

Let's say we have a zippy component.

zippy.component.ts
@Component({
selector: 'zippy',
template: `
<div class="zippy">
<div (click)="toggle()" class="zippy__title">
<span class="arrow">{{ visible ? 'Close' : 'Open' }}</span> {{title}}
</div>
<div *ngIf="visible" class="zippy__content">
<ng-content></ng-content>
</div>
</div>
`
})
export class ZippyComponent {
@Input() title;
visible = false;
toggle() {
this.visible = !this.visible;
}
}

Let's test it.

zippy.component.spec.ts
import { ZippyComponent } from './zippy.component';
import { createHostComponentFactory, SpectatorWithHost } from '@netbasal/spectator';
import { Component } from '@angular/core';
describe('ZippyComponent', () => {
let host: SpectatorWithHost<ZippyComponent>;
const createHost = createHostComponentFactory(ZippyComponent);
it('should display the title', () => {
host = createHost(`<zippy title="Zippy title"></zippy>`);
expect(host.query('.zippy__title')).toHaveText(( text ) => 'Zippy title');
});
it('should have attribute', () => {
host = createHost(`<zippy title="Zippy title">Zippy content</zippy>`);
expect(host.query('.zippy')).toHaveAttr({ attr: 'id', val: 'zippy' });
});
it('should be checked', () => {
host = createHost(`<zippy title="Zippy title">Zippy content</zippy>`);
expect(host.query('.checkbox')).toHaveProp({ prop: 'checked', val: true });
});
it('should display the content', () => {
host = createHost(`<zippy title="Zippy title">Zippy content</zippy>`);
host.click('.zippy__title');
expect(host.query('.zippy__content')).toHaveText('Zippy content');
});
it('should display the "Open" word if closed', () => {
host = createHost(`<zippy title="Zippy title">Zippy content</zippy>`);
expect(host.query('.arrow')).toHaveText('Open');
expect(host.query('.arrow')).not.toHaveText('Close');
});
it('should display the "Close" word if open', () => {
host = createHost(`<zippy title="Zippy title">Zippy content</zippy>`);
host.click('.zippy__title');
expect(host.query('.arrow')).toHaveText('Close');
expect(host.query('.arrow')).not.toHaveText('Open');
}
);
it('should be closed by default', () => {
host = createHost(`<zippy title="Zippy title"></zippy>`);
expect('.zippy__content').not.toExist();
});
it('should toggle the content', () => {
host = createHost(`<zippy title="Zippy title"></zippy>`);
host.click('.zippy__title');
expect(host.query('.zippy__content')).toExist();
host.click('.zippy__title');
expect('.zippy__content').not.toExist();
});
});

First, you need to create a component factory by using the createHostComponentFactory() function, passing the component class that you want to test.

The createHostComponentFactory() function returns a function that will create a fresh component in each itblock, gives you the ability to test each functionality in an isolated environment.

The createHost() function accepts a raw template as the first parameter that Spectator will render inside a default host component.

By default, Spectator will run the initial change detection for you. If you would like to skip it, you can pass a falsy value as the second parameter. For example:

host = createHost("<zippy title="Zippy title"></zippy>", false)

The host method returns an instance of SpectatorWithHost with the following properties:

  • hostFixture - The host's fixture

  • hostComponent - The host's component instance

  • hostElement - The host's native element

  • hostDebugElement - The host's fixture debug element

  • component - The tested component's instance (the zippy component)

  • element - The tested component's native element (the zippy native elemnt)

  • debugElement - The tested component's debug element (the zippy debug element)

Passing complex @Inputs()

If you need to pass a complex object as Input() you can use the third paramater, for example:

it("should support objects", () => {
const options = { color: "blue" }; // options is a Component Input()
host = createHost(`<zippy title="Zippy title"></zippy>`, true, { options });
expect(host.query(".color")).toHaveText("blue");
});

The second option is to use custom host component.