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.
You need to configure all the routing. For testing, rather than using the RouterModule
, you can use the RouterTestingModule
from @angular/router/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'); }); }))); });
Another option, if you just want to test that the routes are rendered correctly, without trying to navigate...
You an just import the RouterTestingModule
without configuring any routes
imports: [ RouterTestingModule ]
then just check that the link is rendered with the correct URL path, e.g.
let href = fixture.debugElement.query(By.css('a')).nativeElement .getAttribute('href'); expect(href).toEqual('/settings/testing/edit/1');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With