No more 💩 angular unit test / #2 Component logic

Alexandre - Nov 17 '19 - - Dev Community

You are looking for testing component template, see here.

⚠️ Use ng-mocks in your unit tests
More details after about this lib. Just keep in mind that it's awesome.

What can we test in component logic ?

  • All Angular Output()
  • All dependency calls

🤔 And what about a component method binded on a button (from html) and dispatch an action for example ?

This case (or similar case) is simply a template test (button interaction) and a logic test (dispatch action when button clicked).

Testing a dependency call

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

describe('YourComponent', () => {
  let service: MyService;

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

    service = TestBed.get(MyService);
  });

  it('should call helloWorld', () => {
    spyOn(service, 'helloWorld');

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

    const actionEl = fixture.debugElement.query(By.css('.action'));
    actionEl.triggerEventHandler('click', {});
    fixture.detectChanges();

    expect(service.helloWorld).toHaveBeenCalled();
  });
});

Enter fullscreen mode Exit fullscreen mode

Testing an output

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

describe('YourComponent', () => {
  let service: MyService;

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

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

    const actionEl = fixture.debugElement.query(By.css('.action'));
    actionEl.triggerEventHandler('click', {});
    fixture.detectChanges();

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

Enter fullscreen mode Exit fullscreen mode

Keep in mind one important thing, if you want to logic, use your template, don't call your logic with fixture.componentInstance.yourMethod() for example.

I hope this article can helps you in your development. 🐼

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .