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

时间:2018-01-27 13:36:15

标签: javascript angular unit-testing karma-jasmine

我正在尝试为具有子组件的组件编写单元测试,并使用//src/reducers/profile.js export default function(state={}, action) { switch(action.type) { case FETCH_DATA_SUCCESS: return { ...state, profile: action.payload }; case FETCH_DATA_FAILED: // Note that I never reach this return { ...state, profile: {} }; case SUBMIT_DATA_SUCCESS: return { ...state, profile: action.payload }; case SUBMIT_DATA_FAILED: return { ...state }; } return state; } 注入。我试图在我的测试中获取组件的queryList,以便我可以在下面测试这个函数,但似乎无法在我的单元测试中填充ng-content变量。

QueryList

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

  @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;
  }
});

}

我如何使用<div class="flex flex-direction-column tabs-container"> <app-tabs (tabChange)='onTabChange($event)' [tabs]="tabs"></app-tabs> <ng-content></ng-content> 组件我这样做(这只是它的模拟版本减去app-tabs组件):

TabsContentContainer

我已尝试按照another answer来确定要做什么,因为这是一个相当古老的答案,但我似乎无法让我的模拟组件返回<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> QueryList

这是我的spec文件:

app-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); });

这导致我添加了一个模拟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.tabContent QueryList

1 个答案:

答案 0 :(得分:2)

问题是,您的TabsContainerMockComponent实际上是TabsContainerComponent之上的包装器。要访问TabsContainerComponent内的TabsContainerMockComponent(可能应该重命名为TestHostTabsContainerComponent),您需要暂停DebugElement并且其中一个孩子(可能是第一个孩子)将成为你的TabsContainerComponent

您需要在顶部使用一个变量来保存TabsContainerComponent

let tabsContainerComponent: TabsContainerComponent;

beforeEach

中执行此操作
tabsContainerComponent = fixture2.debugElement.children[0].componentInstance;

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

tabsContainerComponent.tabContent

在此处详细了解DebugElementhttps://angular.io/api/core/DebugElement