#angular #jestjs #angular-components #angular-test #ngxs
#угловой #jestjs #угловые компоненты #угловой тест #ngxs
Вопрос:
У меня есть эта настройка для ряда компонентов:
@Directive() export abstract class BaseComponent implements OnInit { @Select(PortalState.portal) public portalState: Observablelt;PortalModelgt;; public portal: PortalModel; protected ngUnsubscribe: Subjectlt;voidgt; = new Subject(); constructor( protected someService: SomeService, protected route: ActivatedRoute ){ } public ngOnInit(): void { this.route.params .pipe( filter(res =gt; !!res), tap(res =gt; this.id = res['id']), switchMap(() =gt; this.portalState), takeUntil(this.ngUnsubscribe) ) .subscribe(res =gt; { this.portal = res; this.afterInit(); }); } public ngOnDestroy(): void { this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); } public abstract afterInit(): void }
а затем в каждом компоненте, который расширяет этот базовый класс:
@Component({...}) export class SomeComponent extends BaseComponent { public specificVar: any; constructor( protected someService: SomeService, protected route: ActivatedRoute ){ super(someService, route); } public afterInit(): void { /** do component specific stuff */ this.specificVar = 'something'; } }
Теперь это работает нормально, однако при тестировании ngOnInit абстрактного компонента, похоже, вообще не вызывается, отображая (в этом примере) this.specific
переменную как неопределенную.
файл спецификации выглядит довольно традиционно
let store: Store; /** Ngxs store */ const mockPortalModel: PortalModel = {id: 1}; beforeEach(async () =gt; { TestBed.configureTestingModule(/** providers and usual setup */); store = TestBed.inject(Store); store.reset({ portalState: mockPortalModel }); jest.spyOn(store, 'dispatch'); jest.spyOn(store, 'select'); }); beforeEach(() =gt; { fixture = TestBed.createComponent(SomeComponent); component = fixture.componentInstance; fixture.detectChanges(); });
Есть какие-нибудь идеи, почему ngOnInit
и впоследствии afterInit
не вызываются?
Ответ №1:
Вы должны написать ниже функцию в своем SomeComponent
, чтобы она запускала ваш BaseComponent
ngOnInit
метод после SomeComponent
ngOnInit
метода.
ngOnInit() { super.ngOnInit(); }
Комментарии:
1. Я не думаю, что это правда. Компонент компилируется и отлично работает сам по себе. Речь идет просто о том, чтобы проверить его там, где он терпит неудачу.
Ответ №2:
Проблема заключалась в this.route.params
том, над чем нужно было издеваться, чтобы подписка могла сработать. Таким образом, насмешливый активированный маршрут решил проблему:
const mockActivatedRoute = { snapshot: {}, // needs to be there to avoid _lastPathIndex error params: of({id: 123}) } /** ... */ providers: [ {provide: ActivatedRoute, useValue: mockActivatedRoute } ]
убедился, что подписка проходит (см. Это filter(res =gt; !!res)
— она остановилась прямо там).