As the title indicates, I need to mock router.events
in a unit test.
In my component, I doing some regex to grab the first instance of text between slashes in the url; e.g., /pdp/
constructor(
private route: ActivatedRoute,
private router: Router,
}
this.router.events.pipe(takeUntil(this.ngUnsubscribe$))
.subscribe(route => {
if (route instanceof NavigationEnd) {
// debugger
this.projectType = route.url.match(/[a-z-]+/)[0];
}
});
My unit tests error out when the component is being built: Cannot read property '0' of null
. When I comment-in the debugger, route
does not seem to be set correctly, yet I am setting it in the unit test itself. I have done it several different ways (inspired by this post: Mocking router.events.subscribe() Angular2 and others).
First attempt:
providers: [
{
provide: Router,
useValue: {
events: of(new NavigationEnd(0, '/pdp/project-details/4/edit', 'pdp/project-details/4/edit'))
}
},
// ActivatedRoute also being mocked
{
provide: ActivatedRoute,
useValue: {
snapshot: { url: [{ path: 'new' }, { path: 'edit' }] },
parent: {
parent: {
snapshot: {
url: [
{ path: 'pdp' }
]
}
}
}
}
}
]
Second attempt (based on the above post):
class MockRouter {
public events = of(new NavigationEnd(0, '/pdp/project-details/4/edit', '/pdp/project-details/4/edit'))
}
providers: [
{
provide: Router,
useClass: MockRouter
}
]
Third attempt (also based on above post):
class MockRouter {
public ne = new NavigationEnd(0, '/pdp/project-details/4/edit', '/pdp/project-details/4/edit');
public events = new Observable(observer => {
observer.next(this.ne);
observer.complete();
});
}
providers: [
{
provide: Router,
useClass: MockRouter
}
]
Fourth attempt:
beforeEach(() => {
spyOn((<any>component).router, 'events').and.returnValue(of(new NavigationEnd(0, '/pdp/project-details/4/edit', 'pdp/project-details/4/edit')))
...
Fifth attempt:
beforeEach(() => {
spyOn(TestBed.get(Router), 'events').and.returnValue(of({ url:'/pdp/project-details/4/edit' }))
...
In all the above cases, route
is not being set; the NavigationEnd
object is equal to:
{ id: 1, url: "/", urlAfterRedirects: "/" }
Thoughts?