Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I Mock RouterStateSnapshot for a Router Guard Jasmine test

I have a simple router guard and I am trying to test the canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ). I can create the ActivatedRouteSnapshot like this new ActivatedRouteSnapshot() but I cannot figure out how to create a mocked RouterStateSnapshot.

Per the code I tried...

let createEmptyStateSnapshot = function(     urlTree: UrlTree, rootComponent: Type<any>){     const emptyParams = {};     const emptyData = {};     const emptyQueryParams = {};     const fragment = '';     const activated = new ActivatedRouteSnapshot();     const state = new RouterStateSnapshot(new TreeNode<ActivatedRouteSnapshot>(activated, []));     return {         state: state,         activated: activated     } } 

But import {TreeNode} from "@angular/router/src/utils/tree"; seems to need to be transpiled or something because I get...

Uncaught SyntaxError: Unexpected token export at webpack:///~/@angular/router/src/utils/tree.js:8:0 <- test.bundle.ts:72431

like image 639
Jackie Avatar asked Nov 29 '16 16:11

Jackie


2 Answers

I managed to do it slightly differently but it should work for you :

...  let mockSnapshot:any = jasmine.createSpyObj<RouterStateSnapshot>("RouterStateSnapshot", ['toString']);  @Component({   template: '<router-outlet></router-outlet>' }) class RoutingComponent { }  @Component({   template: '' }) class DummyComponent { }  describe('Testing guard', () => {   beforeEach(() => TestBed.configureTestingModule({     imports: [       RouterTestingModule.withRoutes([         {path: 'route1', component: DummyComponent},         {path: 'route2', component: DummyComponent},         ...       ])   ],   declarations: [DummyComponent, RoutingComponent],   providers: [     GuardClass,     {provide: RouterStateSnapshot, useValue: mockSnapshot}   ] }).compileComponents());    it('should not allow user to overcome the guard for whatever reasons',      inject([GuardClass], (guard:GuardClass) => {       let fixture = TestBed.createComponent(RoutingComponent);       expect(guard.canActivate(new ActivatedRouteSnapshot(), mockSnapshot)).toBe(false);   })  ... 
like image 166
nastyklad Avatar answered Sep 22 '22 14:09

nastyklad


I needed to get the data in the route to test for user roles in my guard, so I mocked it this way:

class MockActivatedRouteSnapshot {     private _data: any;     get data(){        return this._data;     } }  describe('Auth Guard', () => {    let guard: AuthGuard;    let route: ActivatedRouteSnapshot;     beforeEach(() => {       TestBed.configureTestingModule({          providers: [AuthGuard, {             provide: ActivatedRouteSnapshot,             useClass: MockActivatedRouteSnapshot         }]       });       guard = TestBed.get(AuthGuard);   });    it('should return false if the user is not admin', () => {      const expected = cold('(a|)', {a: false});       route = TestBed.get(ActivatedRouteSnapshot);      spyOnProperty(route, 'data', 'get').and.returnValue({roles: ['admin']});       expect(guard.canActivate(route)).toBeObservable(expected);   }); }); 
like image 44
ramon22 Avatar answered Sep 21 '22 14:09

ramon22