angular - Angular 6,如何在子组件上测试父发射器?
问题描述
我有一个选项卡组件作为其子组件的包装器,包装器组件发出状态(打开或关闭)和每个选项卡的索引,在每个子组件上我注入包装器组件以访问发射器。
所以基本上我正在尝试从我的子组件测试文件上的包装器组件订阅发射器:
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});
}
}
解决方案
在您的代码实际发出它之前,您应该订阅事件发射器。以免错过活动。
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();
});
推荐阅读
- vue.js - Vue更新变量并在另一个组件中刷新?
- javascript - 你可以在 forEach() 中使用 splice() 吗?Vue 突变
- php - 根据 Woocommerce 中的订单数设置所有产品状态“缺货”
- r - read_sas(避风港包)中的错误消息使用 cols_only 仅读取列的子集
- node.js - 如何使用 .replace 和 regex 打开和修改 RTF 文件,然后用 Nodejs 逐行编写并删除“顽固”双 \\?
- javascript - 未提交带有ckeditor textarea的Symfony 4表单
- linux - 在 Linux OS 下使用 FASM 使用 XMM 寄存器求和
- c# - Xamarin.Android 项目的 Visual Studio 问题
- css - 保证金底部不适用于广告空间
- awk - AWK:合并表,写入空字段