Directly testing the attribute:
The provided mock ActivatedRoute was messing up the routerLink created href, remove it and the relative paths work great.
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AppComponent],
providers: [
provideRouter([]),
// { provide: ActivatedRoute, useValue: {} } // <- changed here!
],
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
mockDataService = TestBed.inject(DataService);
});
Full Code:
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DataService } from './data.service';
import { AppComponent } from './app.component';
import { ActivatedRoute, provideRouter } from '@angular/router';
import { By } from '@angular/platform-browser';
describe('AppComponent', () => {
let fixture: ComponentFixture<AppComponent>;
let mockDataService: DataService;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AppComponent],
providers: [
provideRouter([]),
// { provide: ActivatedRoute, useValue: {} } // <- changed here!
],
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
mockDataService = TestBed.inject(DataService);
});
it('should use a relative link when there are multiple documents', () => {
spyOnProperty(mockDataService, 'list', 'get').and.returnValue([
{ id: 'One', documents: [{ id: '1' }, { id: '2' }] },
]);
fixture.detectChanges();
const linkEl = fixture.debugElement.query(By.css('a')).nativeElement;
console.log(linkEl);
expect(linkEl.getAttribute('href')).toEqual('/One');
});
it('should use an absolute link when there is only one document', () => {
spyOnProperty(mockDataService, 'list').and.returnValue([
{ id: 'Two', documents: [{ id: '3' }] },
]);
fixture.detectChanges();
const linkEl = fixture.debugElement.query(By.css('a')).nativeElement;
console.log('absolute link', linkEl.getAttribute('href'));
expect(linkEl.getAttribute('href')).toEqual('/documents/3');
});
});
Testing using provideRouter:
We can first add RouterOutlet and the router-outlet selector.
Then create dummy routes with dummy components to provide the fake routes. Then we need to get rid of the activated route mock, since it is messing up the routing.
@Component({ selector: 'dummy' })
export class DummyComponent {}
@Component({ selector: 'dummy2' })
export class DummyComponent2 {}
describe('AppComponent', () => {
let fixture: ComponentFixture<AppComponent>;
let mockDataService: DataService;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AppComponent],
providers: [
provideRouter([
{ path: 'documents/:id', component: DummyComponent },
{ path: ':id', component: DummyComponent2 },
]),
],
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
mockDataService = TestBed.inject(DataService);
});
Now we simply click the a tag and check the route.
it('should use a relative link when there are multiple documents', async () => {
spyOnProperty(mockDataService, 'list', 'get').and.returnValue([
{ id: 'One', documents: [{ id: '1' }, { id: '2' }] },
]);
fixture.detectChanges();
const linkEl = fixture.debugElement.query(By.css('a')).nativeElement;
linkEl.click();
await fixture.whenStable();
expect(TestBed.inject(Router).url).toEqual('/One');
});
Full Code:
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DataService } from './data.service';
import { AppComponent } from './app.component';
import { ActivatedRoute, provideRouter, Router } from '@angular/router';
import { By } from '@angular/platform-browser';
import { Component } from '@angular/core';
@Component({ selector: 'dummy' })
export class DummyComponent {}
@Component({ selector: 'dummy2' })
export class DummyComponent2 {}
describe('AppComponent', () => {
let fixture: ComponentFixture<AppComponent>;
let mockDataService: DataService;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AppComponent],
providers: [
provideRouter([
{ path: 'documents/:id', component: DummyComponent },
{ path: ':id', component: DummyComponent2 },
]),
],
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
mockDataService = TestBed.inject(DataService);
});
it('should use a relative link when there are multiple documents', async () => {
spyOnProperty(mockDataService, 'list', 'get').and.returnValue([
{ id: 'One', documents: [{ id: '1' }, { id: '2' }] },
]);
fixture.detectChanges();
const linkEl = fixture.debugElement.query(By.css('a')).nativeElement;
linkEl.click();
await fixture.whenStable();
expect(TestBed.inject(Router).url).toEqual('/One');
});
it('should use an absolute link when there is only one document', async () => {
spyOnProperty(mockDataService, 'list').and.returnValue([
{ id: 'Two', documents: [{ id: '3' }] },
]);
fixture.detectChanges();
const linkEl = fixture.debugElement.query(By.css('a')).nativeElement;
linkEl.click();
await fixture.whenStable();
expect(TestBed.inject(Router).url).toEqual('/documents/3');
});
});