我有一个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});
}
}
答案 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();
});