loading...
Stack Labs

No more ๐Ÿ’ฉ angular unit test / #1 Component template

ruizalexandre profile image Alexandre Updated on ใƒป2 min read

โš ๏ธ Use ng-mocks in your unit tests
More details after about this lib. Just keep in mind that it's awesome.

Standard first

I love use standard. Angular makes the choice to use Karma/Jasmine, so I continue to use it.

๐Ÿ˜‡ YES, Jest is also a great challenger and a powerful tool to write and execute your unit tests

Testing your components

There are two things to test with your components.

  • Template (.html)
  • Logic (.ts).

Testing template

What can be tested and needed to be tested ?

  • All Angular directive *ngIf, *ngFor, ...
  • All inputs @Input()
  • All outputs @Output()

๐Ÿค” Why we need to test *ngIf for example ?

Image in your commit #1 you add *ngIf in your template without tests. Someone commit the #2 and erase by accident the conditional directive. No test cover this regression.

๐Ÿ”ฅ Use MockRender from ng-mocks to create your component fixture.

import { TestBed } from '@angular/core/testing';
import { YourComponent } from './your-component.component.ts';
import { MockRender } from 'ng-mocks';

describe('YourComponent', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [YourComponent]
    });
  });

  it('should create', () => {
    const fixture = MockRender(`<your-component></your-component>`);
    expect(fixture.componentInstance).toBeTruthy();
  });

  it('should display description', () => {
    const fixture = MockRender(
      `<your-component [description]="description"></your-component>`,
      { description: 'hello world' }
    );
    fixture.detectChanges();

    const descriptionEl = fixture.debugElement.query(By.css('.description');
    expect(descriptionEl.nativeElement.innerHTML).toEqual('hello world');
  });
});

๐Ÿš€ To improve performance and to scope your unit test, use MockComponent from ng-mocks

With this method, child components become black box.

import { TestBed } from '@angular/core/testing';
import { YourComponent } from './your-component.component.ts';
import { YourChildComponent } from './your-child-component.component.ts';
import { MockRender, MockComponent } from 'ng-mocks';

describe('YourComponent', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [YourComponent, MockComponent(YourChildComponent)]
    });
  });

  it('should trigger data', () => {
    let receivedData = null;
    const fixture = MockRender(
        `<my-component (getData)="getData($event)></my-component>`,
        { getData: data => receivedData = data; }
    );
    fixture.detectChanges();

    const triggerDataEl = fixture.debugElement.query(By.css('.trigger-data'));
    const childComponent: YourChildComponent = triggerDataEl.componentInstance;
    childComponent.triggerData.emit('hello world');
    fixture.detectChanges();

    expect(receivedData).toEqual('hello world');
  });
});

In this example, we trigger the output from the child component. And get an output from our component.

Testing logic

In the next post.

I hope this article can helps you in your development. ๐Ÿผ

Posted on by:

Stack Labs

Premier Google Cloud Partner, STACK LABS is a company of tech โค๏ธ enthusiasts at the service of its customers with Cloud, Big Data, Backend, Frontend &amp; Security projects ... Our Partners: Google, AWS, Gitlab

Discussion

markdown guide