我有一条路线,我需要阻止学生访问。 我试图为此编写一个单元测试,但它不起作用。
我的护卫本身的单元测试正在工作,但是当我尝试编写一个导航到/ class的警卫的canActivate方法的测试不会被调用时。
这是守卫:
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { const user = StoreActions.User.getCurrentUser(store.getState()); if(!user) { this.router.navigate(['/pages/login']); return false; } if(user.username.match(/\d/) !== null) { this.router.navigate(['/home']); return false; } return true; }测试:
it( 'should activate guard when a student tries to access /class', fakeAsync( inject([StudentGuard], (guard: StudentGuard) => { const spy = spyOn(guard, 'canActivate'); store.dispatch(StoreActions.User.setCurrentUser(TestObjects.User.Student)); router.navigate(['/class/1']); tick(); expect(spy).toHaveBeenCalled(); discardPeriodicTasks(); }) ) );具体路线如下:
{ path: '', children: { path: 'class', loadChildren: './components/class/class.module#ClassModule', canActivate: [StudentGuard] } }expect声明在测试中失败。 但是,如果我真的冒充一名学生,然后在浏览器中导航到/ class,那么警卫会按预期工作,但是它不会在测试中激活。 我如何在测试中激活它?
I have a route that I need to prevent access from students. I'm trying to write a unit test for this, but it is not working.
My unit tests for the guard itself are working, however when I try to write a test that navigates to /class the canActivate method on the guard does not get called.
Here is the guard:
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { const user = StoreActions.User.getCurrentUser(store.getState()); if(!user) { this.router.navigate(['/pages/login']); return false; } if(user.username.match(/\d/) !== null) { this.router.navigate(['/home']); return false; } return true; }And the test:
it( 'should activate guard when a student tries to access /class', fakeAsync( inject([StudentGuard], (guard: StudentGuard) => { const spy = spyOn(guard, 'canActivate'); store.dispatch(StoreActions.User.setCurrentUser(TestObjects.User.Student)); router.navigate(['/class/1']); tick(); expect(spy).toHaveBeenCalled(); discardPeriodicTasks(); }) ) );Here is the specific route:
{ path: '', children: { path: 'class', loadChildren: './components/class/class.module#ClassModule', canActivate: [StudentGuard] } }The expect statement fails in the test. However, if I actually impersonate a student and then navigate to /class in the browser the guard works as expected, but it does not activate in the test. How can I make it activate in the test?
最满意答案
我只是想出了它。 我发现了几个类似的问题,说业力正在等待观察值得到解决。 我意识到router.navigate返回一个承诺和业力必须等待解决。 我不得不改变我的测试:
it( 'should activate guard when a student tries to access /class', fakeAsync( inject([StudentGuard], (guard: StudentGuard) => { const spy = spyOn(guard, 'canActivate'); store.dispatch(StoreActions.User.setCurrentUser(TestObjects.User.Student)); router.navigate(['/class/1']).then(() => { // added .then expect(spy).toHaveBeenCalled(); // put expect here, AFTER navigate is resolved }); tick(); discardPeriodicTasks(); }) ) );I just figured it out. I found a few questions that were similar saying that karma was waiting for an observable to be resolved. I realized that router.navigate returns a promise and karma must be waiting for that to be resolved. I had to change my test to this:
it( 'should activate guard when a student tries to access /class', fakeAsync( inject([StudentGuard], (guard: StudentGuard) => { const spy = spyOn(guard, 'canActivate'); store.dispatch(StoreActions.User.setCurrentUser(TestObjects.User.Student)); router.navigate(['/class/1']).then(() => { // added .then expect(spy).toHaveBeenCalled(); // put expect here, AFTER navigate is resolved }); tick(); discardPeriodicTasks(); }) ) );更多推荐
发布评论