Reputation: 71
In my Angular 8 application, A component is having an ActivatedRoute class and on the ngOnInit, I am subscribing the route. I have mocked ActivatedRoute in my spec.ts file but cannot set the parent property since it is read-only. It is showing a TypeError: Cannot read property 'parent' of undefined How can we unit test ActivatedRoute in spec.ts?
Here is a code snippet
ngOnInit() {
this.subscriptions.add(this.route.parent.queryParams.subscribe(queryParams =>{
this.Type = queryParams .type
}))}
Upvotes: 1
Views: 3259
Reputation: 26150
You could mock your ActivatedRoute
as follows:
const queryParams = new QueryParams();
queryParams.set('type', '?');
const activatedRouteMock = {
parent: { queryParams: of(queryParams) }
};
The mock would then have to be provided when configuring the testing module inside beforeEach
.
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{ provide: ActivatedRoute, useValue: activatedRouteMock } }
]
....
});
For setting up the activatedRouteMock
I use QueryParams
test class for convenience.
import { ParamMap } from '@angular/router';
export class QueryParams implements ParamMap {
readonly keys: string[] = [];
private params = new Map();
set(name: string, value: string) {
this.keys.push(name);
this.params.set(name, value);
}
get(name: string): string | null {
return this.has(name) ? this.params.get(name) : null;
}
has(name: string): boolean {
return this.params.has(name);
}
getAll(name: string): string[] {
return this.params.has(name) ? [this.params.get(name)] : [];
}
}
UPDATE
In your comment you write, that this doesn't work for the following line of code.
this.subscriptions.add(this.route.parent.parent.parent.params.subscribe(params => { this.Id = params.Id})
This is because here, you chain references to parent
objects. Therefore your activatedRouteMock
must contain more than one nested parent objects as well.
const activatedRouteMock = {
parent: {
queryParams: of(queryParams),
parent: {
parent: { params: of(queryParams) }
}
}
};
Upvotes: 2