#javascript #angular #typescript #jestjs
#javascript #angular #машинописный текст #jestjs
Вопрос:
Я пытаюсь протестировать новый фрагмент кода, который я добавил в свой проект. Это позволяет пользователям выбирать вкладку на странице, и когда они обновляются, страница загружается на ту же вкладку. Для этого я использую localstorage.
Проблема, с которой я сталкиваюсь, заключается в тестах, в которых он не может установить selectedIndex
of undefined
.
В html на вкладке mat у меня есть обработчик событий ( selectedTabChange
):
<mat-tab-group
[selectedIndex]="selectedTab.value"
(selectedIndexChange)="selectedTab.setValue($event)"
(selectedTabChange)="handleMatTabChange($event)"
>
<mat-tab label="Tab 1">
<div *ngIf="selectedTab.value === 0"> ... </div>
</mat-tab>
<mat-tab label="Tab 2">
<div *ngIf="selectedTab.value === 1"> ... </div>
</mat-tab>
<mat-tab label="Tab 3">
<div *ngIf="selectedTab.value === 2"> ... </div>
</mat-tab>
</mat-tab-group>
В компоненте у меня есть
@ViewChild(MatTabGroup) tabGroup: MatTabGroup;
ngAfterViewInit() {
const index = Number(localStorage.getItem('userTabLocation')) || 0;
this.tabGroup.selectedIndex = index;
}
handleMatTabChange(event: MatTabChangeEvent) {
localStorage.setItem('userTabLocation', String(event.index));
}
Тесты:
Проверка, определен ли ViewChild, но это undefined
.
it('Should have `ViewChild` variable defined', () => {
expect(component.tabGroup).toBeDefined();
});
Также в некоторых других моих тестах я получаю:
TypeError: Cannot set property 'selectedIndex' of undefined
99 | }
100 |
> 101 | ngAfterViewInit() {
| ^
102 | const index = Number(localStorage.getItem('userTabLocation')) || 0;
103 | this.tabGroup.selectedIndex = index;
Вещи, которые я пробовал:
- Я прочитал эту действительно полезную статью https://blog.angularindepth.com/angular-unit-testing-viewchild-4525e0c7b756
-
Поскольку мой дочерний элемент view является MatTabGroup, я понятия не имею, как его отключить, поэтому приведенная выше статья не очень помогла. Я пробовал это, но это нарушило еще больше тестов:
component.tabGroup = TestBed.createComponent(MatTabGroup).componentInstance as MatTabGroup;
-
Я добавил MatTabGroup в провайдеры подобным образом, что не помогло:
TestBed.configureTestingModule({ imports: [ ... ], declarations: [ ... ], providers: [ { provide: MatTabGroup, }], }).compileComponents();
-
Я добавил значения useValues в провайдеры с matTabGroup вот так, что также не помогло:
TestBed.configureTestingModule({ imports: [ ... ], declarations: [ ... ], providers: [ { provide: MatTabGroup, useValues: { selectedIndex: 0, } }], }).compileComponents();
-
Я добавил
MatTabsModule
в импорт, также не повезло:TestBed.configureTestingModule({ imports: [ MatTabsModule ], declarations: [ ... ], }).compileComponents();
Но это выдает следующую ошибку:
Template parse errors: More than one component matched on this element. Make sure that only one component's selector can match a given element. Conflicting components: MatTab,MatTab ("
(РЕДАКТИРОВАТЬ): это происходило потому, что я тоже импортировал
MaterialModule
.
Есть идеи? Действительно застрял на этом.
Заранее благодарю вас.
Комментарии:
1. Используя Jasmine и Karma,
tabGroup
не будет определен до тех пор, пока не будет выполнен хук ngAfterViewInit — я бы предположил, что вам нужно будет выполнитьfixture.detectChanges()
, а затем дождатьсяfixture.whenStable()
возврата обещания, прежде чем оно будет установлено в тестовой среде. С помощью Jest вам нужно будет выполнить любой эквивалент в этой среде.