Published September 29, 2019
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'
}
}
},
},
},
}
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,
}),
},
},
Joshua Colvin is a UI Software Engineer specializing in building component libraries. He lives with his wife and two kids in Michigan.