Тестирование canLoad ()
В отличие от canActivate()
, canLoad()
требует только аргумента Route. То есть canLoad(route: Route):boolean
против canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot )
. Route
- это просто интерфейс, который мы используем для определения и экспорта маршрутов, и он уже должен существовать в контексте модуля TestBed. Следовательно, вам вообще не нужно издеваться над ним или создавать новый экземпляр.
В вашей функции жасмина beforeEach (async ()) импортируйте RouterTestingModule с маршрутами.
TestBed.configureTestingModule({
imports: [HttpClientModule, ... ..., RouterTestingModule.withRoutes(routes)],
...
providers: [AuthenticationService, LoadGuard ] //only need to provide it here!
})
с routes
является export const routes: Routes = [{}]
, который вы определили с loadChildren
и canLoad
.
Обратите внимание на это, импортируя RouterTestingModule автоматически предоставляет (то есть внедряет) следующие услуги:
- Расположение
- LocationStrategy
- NgModuleFactoryLoader
- PreloadingStrategy
- Маршрутизатор
Как видно из этой ссылки на документы API: https://angular.io/api/router/testing/RouterTestingModule#providers
Из-за этого вы можете просто ссылаться на эти введенные услуги без насмешки над ними , как вы это сделали.
В вашей функции description () jasmine объявите следующее:
describe('AppComponent', () => {
... //all your other declarations like componentFixture, etc
loadGuard: LoadGuard;
authService: AuthenticationService;
router: Router;
location: Location;
loader: NgModuleFactoryLoader;
...
});
В вашей функции beforeEach () с жасмином:
location = TestBed.get(Location); //these already exist in TestBed context because of RouterTestingModule
router = TestBed.get(Router);
... //other declarations
loadGuard = TestBed.get(LoadGuard);
authService = TestBed.get(AuthenticationService);
Теперь цель этого модульного теста - проверить маршрутизацию и определить, загружен ли соответствующий модуль на самом деле.
Следовательно, вам также нужно заглушить лениво загруженные модули в вашей функции beforeEach () jasmine:
loader = TestBed.get(NgModuleFactoryLoader); //already exists in TestBed context because of RouterTestingModule
loader.stubbedModules = {
'./areas/home/home.module#HomeModule': HomeModule,
... //other lazily loaded modules
}
fixture.detectChanges();
Поскольку вы уже импортировали свои маршруты в configureTestingModule()
, как уже упоминалось выше, вам не нужно сбрасывать конфигурацию маршрутизатора, как этого требуют спецификации API (https://angular.io/api/router/testing/SpyNgModuleFactoryLoader#description).
Со всей этой настройкой вы готовы проверить защиту canLoad ().
it('if X claims is false, user shouldn't be able to load module', fakeAsync(() => {
spyOn(authService, 'checkClaims').and.returnValue(false);
fixture.detectChanges();
router.navigateByUrl('XRoute');
tick();
expect(location.path()).toBe('/"unauthorised'); //or /404 depending on your req
}))
Вам не нужно больше издеваться или создавать шпионские объекты, а что нет.
Хотя этот ответ запаздывает на несколько месяцев, и, скорее всего, он вам сейчас даже не нужен. Надеюсь, опубликовав его, он поможет другим разработчикам Angular, так как это единственный вопрос в Stackoverflow, который специально задал вопрос о модульном тестировании canLoad (), с которым я тоже столкнулся.