首页 > 解决方案 > 如何开玩笑地模拟@ViewChild MatTabGroup?

问题描述

我正在尝试测试我添加到项目中的一段新代码。它允许用户在页面上选择一个选项卡,当他们刷新时,页面会加载到同一个选项卡上。我正在使用本地存储来执行此操作。

我遇到的问题是在无法设置的测试selectedIndexundefined

在 mat-tab 的 html 中,我有一个事件处理程序 ( 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;

我尝试过的事情:

  1. 我读了这篇非常有用的文章https://blog.angularindepth.com/angular-unit-testing-viewchild-4525e0c7b756
  2. 由于我认为孩子是一个 MatTabGroup,我不知道如何存根,所以上面的文章没有多大帮助。我试过了,但这打破了更多的测试:

    component.tabGroup = TestBed.createComponent(MatTabGroup).componentInstance as MatTabGroup;
    
  3. 我已经像这样将 MatTabGroup 添加到提供程序中,但这没有帮助:

    TestBed.configureTestingModule({
          imports: [ ... ],
          declarations: [ ... ],
          providers: [
          {
             provide: MatTabGroup,
          }],
    }).compileComponents();
    
  4. 我已经像这样使用 matTabGroup 将 useValues 添加到提供程序中,这也没有帮助:

    TestBed.configureTestingModule({
          imports: [ ... ],
          declarations: [ ... ],
          providers: [
          {
             provide: MatTabGroup,
             useValues: {
                selectedIndex: 0,
             }
          }],
    }).compileComponents();
    
  5. 我已将其添加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

有任何想法吗?真的卡在这上面了。

先感谢您。

标签: javascriptangulartypescriptjestjs

解决方案


推荐阅读