测试Lit Element resize事件解绑时Jasmine Spy被错误调用问题
问题根因
- 核心是事件监听的函数引用和你挂载Spy的函数引用不一致,加上测试用例间共享组件实例导致的状态污染:
- 类属性
getPositionEvent在组件初始化时就会生成第一个固定的bind后的原始函数引用,如果你在addEventListener执行之后才给这个属性挂载Spy,那么window上实际绑定的是未被Spy包装的原始引用,后续你对getPositionEvent属性的Spy替换,不会影响已经绑定到window上的函数引用。 - 你看到日志没有打印,说明window上绑定的原始引用确实已经被成功解绑,Spy计数异常增加是因为你测试代码的其他逻辑主动调用了已经被Spy包装后的
component.getPositionEvent,而非resize事件触发的调用。 - 如果你挂载Spy时没有加
.and.callThrough(),Spy被调用时不会执行原始函数,也会出现日志不打印但Spy计数上升的情况。
- 类属性
修复方案
- 每个测试用例前创建独立的组件实例,废弃
beforeAll初始化组件的逻辑,改为在beforeEach中生成新实例,避免用例间状态互相影响。 - 严格控制测试时序,必须在调用
connectedCallback之前完成Spy的挂载,保证addEventListener绑定的就是被Spy包装后的函数引用:// 正确的Spy设置逻辑 const getPositionEventSpy = spyOn(component, 'getPositionEvent').and.callThrough(); - 解绑测试固定执行时序:
- 初始化全新组件实例
- 挂载带
callThrough的Spy - 调用
connectedCallback完成事件绑定 - 调用
disconnectedCallback移除事件监听 - 重置Spy的调用计数
- 派发window的resize事件
- 验证Spy调用次数为0
内容的提问来源于stack exchange,提问作者Stephen Agwu
相关产品推荐
相关产品推荐

