我有一条路线需要阻止学生访问。我正在尝试为此编写单元测试,但它无法正常工作。
我对守卫本身的单元测试工作正常,但是当我尝试编写一个导航到/ 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,则防护按预期工作,但它不会在测试中激活。如何在测试中激活它?
答案 0 :(得分:1)
我只是想通了。我发现了几个类似的问题,说业力正在等待一个可观察的问题得到解决。我意识到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();
})
)
);