Mocking Route params in Angular unit tests
A guide on how to mock ActivatedRoute params and snapshot data in Angular unit tests.
Mocking activated route snapshot params
It’s common, in Angular, to access route parameters when the component is initialized. This can be done using the ActivatedRouteSnaphot:
ngOnInit() {
this.bookId = +this.activatedRoute.snapshot.paramMap.get('bookId');
this.getBook(this.bookId);
}
Since the activatedRoute is accessed inside of ngOnInit, we will need to mock the activatedRoute in our unit tests. We can provide the ActivatedRoute in the testing module but use a different value that we have full control over in its place:
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{
provide: ActivatedRoute,
useValue: {
snapshot: {
paramMap: {
get: () => 1, // represents the bookId
},
},
},
},
],
declarations: [BookComponent],
}).overrideComponent(BookComponent, {
set: {
template: '',
},
})
})
If we only care about one paramater contained in paramMap, like in the example above, we can return this parameter directly from the get method: get: () => 1. If there are multiple parameters we care about we can use a switch statement instead:
{
provide: ActivatedRoute,
useValue: {
snapshot: {
paramMap: {
get: (key: string) => {
switch (key) {
case 'bookId':
return 2;
case 'genre':
return 'fiction'
}
}
},
},
},
}
With activated route param observables
We might subscribe to the ActivatedRoute params instead:
ngOnInit() {
this.activatedRoute.params.subscribe(params => {
this.bookId = parseInt(params.bookId, 10)
this.getBookById(this.bookId)
})
}
We are still able to mock the router params but params will need to return an observable to allow our subscription to work. We can do this by using the RxJs of operator:
import { of } from 'rxjs';
...
{
provide: ActivatedRoute,
useValue: {
params: of({
bookId: 2,
}),
},
},