Skip to content

Instantly share code, notes, and snippets.

@allenhwkim
Last active May 4, 2020 19:42
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save allenhwkim/a281649182702cc20d2b8b1c56d1d06e to your computer and use it in GitHub Desktop.
Save allenhwkim/a281649182702cc20d2b8b1c56d1d06e to your computer and use it in GitHub Desktop.
Angular5+ Unit Tests

I do not want fixture.detectChanges() called automatically.

test

import { async, ComponentFixtureAutoDetect, TestBed } from '@angular/core/testing';

describe('NguiVirtualListComponent', () => {
  ...
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      providers: [
        { provide: ComponentFixtureAutoDetect, useValue: true },
        ...

How to test constructor with various parameters. e.g. a service, ElementRef?

Error case:

  • No provider for ElementRef!
  • No provider for XXXXService!

code

  constructor(
    public renderer: Renderer2,
    public element: ElementRef,   // <-- mock required
    public dynamicComponentService: DynamicComponentService, // <-- mock required
    public cdr: ChangeDetectorRef,
    @Inject(PLATFORM_ID) private platformId: any
  ) {}

test

import { ChangeDetectorRef, ElementRef, Injectable, Renderer2 } from '@angular/core';

import { DynamicComponentService } from '../../utils';

class MockElementRef extends ElementRef {
  constructor() { super(undefined); }
  // nativeElement = {};
}

class MockDynamicComponentService extends DynamicComponentService {
}

describe('NguiVirtualListComponent', () => {
  let fixture;
  let component;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        NguiVirtualListComponent,
        MockComponent('ngui-inview')
      ],
      providers: [
        Renderer2,
        ChangeDetectorRef,
        { provide: ComponentFixtureAutoDetect, useValue: true },
        { provide: ElementRef, useClass: MockElementRef },
        { provide: DynamicComponentService, useClass: MockDynamicComponentService },
        { provide: PLATFORM_ID, useValue: 'browser'}
      ]
      // schemas: [NO_ERRORS_SCHEMA]
    }).compileComponents();
  }));
  
  it('should create a component', async(() => {
    fixture = TestBed.createComponent(NguiVirtualListComponent);
    component = fixture.debugElement.componentInstance;

    expect(component).toBeTruthy();
  }));
  ...

mock existing function

test

    component.myFunc = jest.fn().mockReturnValue(true)
    
    component.ngOnInit();
    expect(component.myFunc).toHaveBeenCalled();

mock getter

test

Object.defineProperty(myObj, 'prop', {
  get: jest.fn(() => 'bar'),
  set: jest.fn()
});

mock document HTML

Ref. https://facebook.github.io/jest/docs/en/tutorial-jquery.html

test

  document.body.innerHTML = '<input id="my-input" />;

mock windows object

Error Case

  • ReferenceError: IntersectionObserver is not defined

code

  ngOnInit(): void {
    if (isPlatformBrowser(this.platformId)) {
      this.observer = new IntersectionObserver(this.handleIntersect.bind(this), this.options);
      this.observer.observe(this.element.nativeElement);
    }
  }

test

(<any>window).IntersectionObserver = jest.fn();
IntersectionObserver.prototype.observe = jest.fn();

describe('MyComponent', () => {
  it('should run #ngOnInit', async(() => {
    component.ngOnInit();
    expect(component.observer).toBeTruthy();
  }));
});

test console.error

code

  foo(): void {
    console.error('<ngui-virtual-list> requires [template] and {bottomInview)');
  }

test

  it('should test console.error', async(() => {
    const spyError = jest.spyOn(console, 'error');
    component.foo();
    
    expect(spyError).toHaveBeenCalled();
  }));

Exception Test

code

function foo() {
  throw 'error';
}

test

  expect(() => {
    foo();
  }).toThrow();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment