When I provide params to my TestComponent
the test bed blows up if the html contains a [routerLink]
testbed setup
TestBed.configureTestingModule({
imports: [SharedModule.forRoot(), ManagementModule, HttpModule, RouterModule.forRoot([{
path: '', component: TestComponent
}])],
declarations: [TestComponent],
providers: [
BaseRequestOptions,
MockBackend,
{
provide: Http, useFactory: function (backend: MockBackend, defaultOptions: BaseRequestOptions) {
return new Http(backend, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions]
},
{ provide: APP_BASE_HREF, useValue: '/' },
{
provide: ActivatedRoute,
useValue: {
params: Observable.of({ versionId: '1' }),
parent: {
params: Observable.of({ uniqueId: '1234' })
}
}
}
]
});
TestBed.compileComponents();
});
Error logged
Failed: Error in ./DetailComponent class DetailComponent - inline template:72:20 caused by: Cannot read property '_lastPathIndex' of undefined
TypeError: Cannot read property '_lastPathIndex' of undefined
at findStartingPosition (webpack:///home/developer/Projects/project/~/@angular/router/src/create_url_tree.js:184:0 <- src/test.ts:100429:23)
at createUrlTree (webpack:///home/developer/Projects/project/~/@angular/router/src/create_url_tree.js:27:21 <- src/test.ts:100272:45)
at Router.createUrlTree (webpack:///home/developer/Projects/project/~/@angular/router/src/router.js:424:0 <- src/test.ts:28688:111)
at RouterLinkWithHref.get [as urlTree] (webpack:///home/developer/Projects/project/~/@angular/router/src/directives/router_link.js:253:0 <- src/test.ts:50778:32)
at RouterLinkWithHref.updateTargetUrlAndHref (webpack:///home/developer/Projects/project/~/@angular/router/src/directives/router_link.js:246:0 <- src/test.ts:50771:91)
at RouterLinkWithHref.ngOnChanges (webpack:///home/developer/Projects/project/~/@angular/router/src/directives/router_link.js:217:67 <- src/test.ts:50742:74)
at Wrapper_RouterLinkWithHref.ngDoCheck (/RouterModule/RouterLinkWithHref/wrapper.ngfactory.js:101:18)
at DebugAppView.View_DetailComponent3.detectChangesInternal (/ManagementModule/DetailComponent/component.ngfactory.js:548:33)
at DebugAppView.AppView.detectChanges (webpack:///home/developer/Projects/project/~/@angular/core/src/linker/view.js:425:0 <- src/test.ts:95635:14)
at DebugAppView.detectChanges (webpack:///home/developer/Projects/project/~/@angular/core/src/linker/view.js:620:0 <- src/test.ts:95830:44)
at ViewContainer.detectChangesInNestedViews (webpack:///home/developer/Projects/project/~/@angular/core/src/linker/view_container.js:67:0 <- src/test.ts:95967:37)
at DebugAppView.View_DetailComponent0.detectChangesInternal (/ManagementModule/DetailComponent/component.ngfactory.js:85:14)
at DebugAppView.AppView.detectChanges (webpack:///home/developer/Projects/project/~/@angular/core/src/linker/view.js:425:0 <- src/test.ts:95635:14)
at DebugAppView.detectChanges (webpack:///home/developer/Projects/project/~/@angular/core/src/linker/view.js:620:0 <- src/test.ts:95830:44)
template line 72
<a class="button" [routerLink]="['/']">Back</a>
In an ideal world i'd like to continue providing the params, any idea why its blowing up?
I figured out the problem/solution.
We're seeing Cannot read property '_lastPathIndex' of undefined
because at one point the Angular router expects a _lastPathIndex
property on a snapshot
object.
The relevant part of the Angular source code looks like this:
if (route.snapshot._lastPathIndex === -1) {
return new Position(route.snapshot._urlSegment, true, 0);
}
If snapshot
is undefined, it will of course raise the error we're seeing.
The problem can be solved by making snapshot
not-undefined.
Here's how I did it. My code is a little different from the OP's.
I have a class called MockActivatedRoute
that looks like this.
export class MockActivatedRoute {
parent: any;
params: any;
constructor(options) {
this.parent = options.parent;
this.params = options.params;
}
}
Here's how I use it in my test.
let mockActivatedRoute = new MockActivatedRoute({
parent: new MockActivatedRoute({
params: Observable.of({ id: '1' })
})
});
To make the error go away I just added a snapshot
property to MockActivatedRoute
.
export class MockActivatedRoute {
parent: any;
params: any;
snapshot = {};
constructor(options) {
this.parent = options.parent;
this.params = options.params;
}
}