select select - 2 months ago 382
TypeScript Question

Angular 2 unit testing components with routerLink

I am trying to test my component with angular 2 final, but I get an error because the component uses the

routerLink
directive. I get the following error:


Can't bind to 'routerLink' since it isn't a known property of 'a'.


This is the relevant code of the
ListComponent
template

<a
*ngFor="let item of data.list"
class="box"
routerLink="/settings/{{collectionName}}/edit/{{item._id}}">


And here is my test.

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

import { ListComponent } from './list.component';
import { defaultData, collectionName } from '../../config';
import { initialState } from '../../reducers/reducer';


const data = {
sort: initialState.sort,
list: [defaultData, defaultData],
};

describe(`${collectionName} ListComponent`, () => {
let fixture;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
ListComponent,
],
}).compileComponents(); // compile template and css;
fixture = TestBed.createComponent(ListComponent);
fixture.componentInstance.data = data;
fixture.detectChanges();
});

it('should render 2 items in list', () => {
const el = fixture.debugElement.nativeElement;
expect(el.querySelectorAll('.box').length).toBe(3);
});
});


I looked at several answers to similar questions but could not find a solution that worked for me.

Answer

You need to configure all the routing. For testing, rather than using the RouterModule, you can use the RouterTestingModule from @angular/core/testing, where you can set up some mock routes. You will also need to import the CommonModule from @angular/common for your *ngFor. Below is a complete passing test

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { By } from '@angular/platform-browser';
import { Location, CommonModule } from '@angular/common';
import { RouterTestingModule } from '@angular/router/testing';
import { TestBed, inject, async } from '@angular/core/testing';

@Component({
  template: `
    <a routerLink="/settings/{{collName}}/edit/{{item._id}}">link</a>
    <router-outlet></router-outlet>
  `
})
class TestComponent {
  collName = 'testing';
  item = {
    _id: 1
  };
}

@Component({
  template: ''
})
class DummyComponent {
}

describe('component: TestComponent', function () {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        CommonModule,
        RouterTestingModule.withRoutes([
         { path: 'settings/:collection/edit/:item', component: DummyComponent }
        ])
      ],
      declarations: [ TestComponent, DummyComponent ]
    });
  });

  it('should go to url',
    async(inject([Router, Location], (router: Router, location: Location) => {

    let fixture = TestBed.createComponent(TestComponent);
    fixture.detectChanges();

    fixture.debugElement.query(By.css('a')).nativeElement.click();
    fixture.whenStable().then(() => {
      expect(location.path()).toEqual('/settings/testing/edit/1');
      console.log('after expect');
    });
  })));
});
Comments