角度6,如何在子组件上测试父发射器?

时间:2018-07-11 19:30:51

标签: angular unit-testing jasmine subscription eventemitter

我有一个tab组件作为带有其子组件的包装器,包装器组件发出状态(打开或关闭)和每个标签的索引。在每个子组件上,我注入包装器组件以访问发射器。

所以基本上,我试图从子组件测试文件上的包装器组件中订阅发射器:

it(`it should have a 'toggle()' function that close/open the tab and then emits the tab status`, (emitted) => {

    fixture = TestBed.createComponent(AccordionTabComponent);
    const compiled = fixture.componentInstance;

    compiled.toggle(); // -> toggle function trigger the emit

    const data = {
      tabIndex: compiled.tabIndex,
      isOpen: compiled.isOpen
    }; // -> I get the current data from the child component to compare it with the emitted data.

    compiled.accordionRef.open.subscribe(tabEmmited => {
      console.log('tabEmmited: ', tabEmmited);
      expect(JSON.stringify(data)).toBe(JSON.stringify(tabEmmited));
      emitted();
    });

    fixture.detectChanges();    
});

但是看起来订阅从未发生,因为“订阅”中的“日志”从不打印任何内容,这也导致此错误:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

以下是我组件中的一些代码,以获取更多上下文:

包装器组件:

 export class AccordionComponent implements OnInit {

  @ContentChildren(forwardRef(() => AccordionTabComponent)) public childrenTabs: QueryList<AccordionTabComponent>;
  @Output() open: EventEmitter<{}> = new EventEmitter(); // -> Parent emitter.
 }

标签组件:

    export class AccordionTabComponent implements OnInit {
        accordionRef: AccordionComponent; -> Wrapper Component Ref
        tabIndex: number;
        isOpen: boolean;

        constructor(
          @Inject(AccordionComponent) accordionContainer: AccordionComponent -> Wrapper component injected
      ) {
            this.accordionRef = accordionContainer;
          }

      // Show/Hide tab
        toggle(): void {
          this.isOpen = !this.isOpen;
          this.accordionRef.open.emit({tabIndex: this.tabIndex, isOpen: this.isOpen});
        }
     }

1 个答案:

答案 0 :(得分:1)

您应该先订阅事件发射器,然后再实际发射它。这样您就不会错过活动。

it(`it should have a 'toggle()' function that close/open the tab and then emits the tab status`, (emitted) => {
    fixture = TestBed.createComponent(AccordionTabComponent);
    const compiled = fixture.componentInstance;

    //subscribe before emitting
    compiled.accordionRef.open.subscribe(tabEmmited => {
          expect(JSON.stringify(data)).toBe(JSON.stringify(tabEmmited));
    });

    compiled.toggle(); // -> Call the method that actually emits it

    ..........

    fixture.detectChanges();    
});