使用@ContentChildren对查询列表进行单元测试

sau*_*ers 5 javascript unit-testing karma-jasmine angular

我正在尝试为具有子组件并使用 注入的组件编写单元测试ng-content。我试图在测试中获取组件的查询列表,以便我可以在下面测试此函数,但似乎无法QueryList在单元测试中填充变量。

  @ContentChildren(TabsContentComponent, { descendants: true, read: TabsContentComponent }) tabContent: QueryList<TabsContentComponent>;
onTabChange($event) {
this.tabContent.toArray().forEach((tab, index) => {
  tab.isActive = false;
  if ($event.value === tab.value) {
    tab.isActive = true;
  }
});

}
Run Code Online (Sandbox Code Playgroud)

这是我的组件:我有一个名为 TabsContentContainer 的组件,其中包含另一个名为 Tabs 的组件。看起来像这样:

<div class="flex flex-direction-column tabs-container">
<app-tabs (tabChange)='onTabChange($event)' [tabs]="tabs"></app-tabs>
<ng-content></ng-content>
Run Code Online (Sandbox Code Playgroud)

我如何使用TabsContentContainer该组件(这只是它的模拟版本,减去了 app-tabs 组件):

<app-tabs-container>
<app-tabs-content>content goes here</app-tabs-content>
<app-tabs-content>content goes here</app-tabs-content>
<app-tabs-content>content goes here</app-tabs-content>
Run Code Online (Sandbox Code Playgroud)

我尝试遵循另一个答案来弄清楚该怎么做,因为它是相当旧的答案,但我似乎无法让我的模拟组件返回我QueryListapp-tabs-content.

这是我的规格文件:

    @Component({
  selector: 'app-tabs-container-mock-component',
  template: `<app-tabs-container>
    <app-tabs-content></app-tabs-content>
    <app-tabs-content></app-tabs-content>
    <app-tabs-content></app-tabs-content>
  </app-tabs-container>`
})
export class TabsContainerMockComponent { }

fdescribe('TabsContainerComponent', () => {
  let component: TabsContainerComponent;
  let component2: TabsContainerMockComponent;
  console.log(component2);
  let fixture: ComponentFixture<TabsContainerComponent>;
  let fixture2: ComponentFixture<TabsContainerMockComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [TabsContainerComponent, TabsContainerMockComponent],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(TabsContainerComponent);
    fixture2 = TestBed.createComponent(TabsContainerMockComponent);
    console.log(fixture2);
    component = fixture.componentInstance;
    component2 = fixture2.componentInstance;
    fixture.detectChanges();
    fixture2.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
    expect(component2).toBeTruthy();
  });

  it('should show the correct content when changing tabs', () => {
    const container = fixture.debugElement.children[0].componentInstance;
    debugger;
    console.log(container);
  });
Run Code Online (Sandbox Code Playgroud)

我尝试过的

我尝试模拟我的组件并尝试访问它,但这似乎不起作用,因为我收到错误抱怨Component 'TabsContainerMockComponent' is not included in a module and will not be available inside a template. Consider adding it to a NgModule declaration

这导致我添加了一个模拟NgModule,但这也不起作用,而且看起来也不正确。

我不知道该尝试什么,因为我似乎无法达到component.tabContenta QueryListof app-tabs-content

vin*_*nce 4

问题是现在你的TabsContainerMockComponent实际上是你的TabsContainerComponent. 为了访问TabsContainerComponent您的内部TabsContainerMockComponent(可能应该重命名为类似的东西TestHostTabsContainerComponent),您需要掌握 ,DebugElement并且它的一个孩子(可能是第一个孩子)将是您的TabsContainerComponent

您需要在顶部有一个变量来保存您的TabsContainerComponent

let tabsContainerComponent: TabsContainerComponent;
Run Code Online (Sandbox Code Playgroud)

在您的beforeEach

tabsContainerComponent = fixture2.debugElement.children[0].componentInstance;
Run Code Online (Sandbox Code Playgroud)

然后您可以访问您的,QueryList因为它是公共财产TabsContainerComponent

tabsContainerComponent.tabContent
Run Code Online (Sandbox Code Playgroud)

在这里阅读更多信息DebugElement: https: //angular.io/api/core/DebugElement