Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular testing router params breaks test bed

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?

like image 816
JohnC Avatar asked Dec 20 '16 15:12

JohnC


1 Answers

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;   } } 
like image 87
Jason Swett Avatar answered Oct 23 '22 05:10

Jason Swett