如何在Jasmine测试中模拟触发事件回调以调用目标方法
问题描述
组件代码
function aa() { this.component.grid = createItem(); this.component.grid.instance.options.addEventListener('eventAbc',() => { this.bbb (); }) } function bbb() { console.log("dummy func"); }
现有测试代码(component.spec.ts)
let content; setup() { content = jasmine.createSpyObj('content', ['createItem']); content.createItem.and.callFake(() => { return { grid: { instance: { options: { addEventListener: (event, action) => {} }}}}} it('testing method aa', () => { spyOn(component.grid.instance.gridOptions, 'addEventListener').andCallThrough(); spyOn(component, 'bbb').and.callThrough(); component.aa(); expect(component.grid.instance.gridOptions.addEventListener).toHaveBeenCalled(); expect(component.bbb).toHaveBeenCalled(); }
需求:如何模拟触发eventAbc事件,让测试进入事件监听器的真实回调函数并调用bbb方法?
解决方案
要触发事件并执行回调,核心是在模拟addEventListener时保存传入的回调函数,之后主动调用它即可,具体修改如下:
修改
setup中的模拟逻辑,保存事件回调
在createItem的模拟返回值里,修改addEventListener的实现,把eventAbc对应的回调函数存下来,方便后续调用:let content; setup() { content = jasmine.createSpyObj('content', ['createItem']); // 定义变量存储eventAbc的回调函数 let eventAbcCallback; content.createItem.and.callFake(() => { return { grid: { instance: { options: { addEventListener: (event, action) => { // 匹配到eventAbc时,保存回调 if (event === 'eventAbc') { eventAbcCallback = action; } } } } } } }); // 将回调挂载到content上,让测试用例可以访问 content.eventAbcCallback = eventAbcCallback; }在测试用例中调用回调,模拟事件触发
执行component.aa()完成事件监听绑定后,直接调用保存的回调函数,就能触发bbb方法:it('testing method aa', () => { spyOn(component, 'bbb').and.callThrough(); // 执行aa方法完成事件监听绑定 component.aa(); // 调用保存的回调,模拟eventAbc事件触发 content.eventAbcCallback(); // 验证bbb方法被调用 expect(component.bbb).toHaveBeenCalled(); // 验证addEventListener确实监听了eventAbc事件 expect(content.createItem().grid.instance.options.addEventListener).toHaveBeenCalledWith('eventAbc', jasmine.any(Function)); });
补充说明
- 原测试代码中的
component.grid.instance.gridOptions疑似笔误,需和组件里的this.component.grid.instance.options保持变量名一致; - 无需额外
spyOn并andCallThrough监听addEventListener,直接在模拟实现中保存回调更高效; - 调用回调函数的操作,等价于模拟了
eventAbc事件被触发,此时会自动执行回调内的this.bbb()逻辑。
内容的提问来源于stack exchange,提问作者Saranya Garimella
相关产品推荐
相关产品推荐

