I need help in order to write unit tests for router.events.subscribe
. I used ActivationEnd
to use snapshot object which has properties which I need for my application. No other events from router provide these so I have to stick to this ActivationEnd
. But I did not get anything so far as to how to mock this snapshot object.
Below is my code snippet.
ngOnInit() {
this.router.events.subscribe(e => {
if (e instanceof ActivationEnd) {
this.section = e.snapshot.data.title;
this.dynamicSubNavLabel = e.snapshot.routeConfig?.data?.label;
}
});
}
Can you please help me what could I do to achieve unit tests for this or any alternatives ?
Regards, Alpesh
Let say, you have a component like this:
import { Component, OnInit } from '@angular/core';
import { ActivationEnd, Router } from '@angular/router';
@Component({
selector: 'app-test-router',
templateUrl: './test-router.component.html',
styleUrls: ['./test-router.component.css']
})
export class TestRouterComponent implements OnInit {
section = '';
dynamicSubNavLabel = '';
constructor(private router: Router) { }
ngOnInit() {
this.router.events.subscribe(e => {
if (e instanceof ActivationEnd) {
this.section = e.snapshot.data.title;
this.dynamicSubNavLabel = e.snapshot.routeConfig?.data?.label;
}
});
}
}
Because Router.events
is a Subject<Event>
already. We can do this:
Subject<Event>
then call next
to emit our custom/mock ActivationEnd Event.import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRouteSnapshot, ActivationEnd, Event, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { Subject } from 'rxjs';
import { TestRouterComponent } from './test-router.component';
describe('TestRouterComponent', () => {
let component: TestRouterComponent;
let fixture: ComponentFixture<TestRouterComponent>;
let router: Router;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [ TestRouterComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(TestRouterComponent);
component = fixture.componentInstance;
router = TestBed.inject(Router);
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should update data from router', () => {
const events$ = router.events as Subject<Event>;
const mockSnapshot = {
data: {
title: 'some heading'
},
routeConfig: {
data: {
label: 'some text'
}
}
} as unknown as ActivatedRouteSnapshot;
events$.next(new ActivationEnd(mockSnapshot));
expect(component.section).toBeTruthy();
expect(component.dynamicSubNavLabel).toBeTruthy();
})
});
Source code from Angular: https://github.com/angular/angular/blob/75a3c778b1f7be913f0287423d40fade68ee9adc/packages/router/src/router.ts#L461