Jest测试点击按钮触发focus()时报错is not a function的问题求助
问题原因
报错focus 不是函数是因为this.hiddenTextRef在调用focus方法时未正确指向DOM元素,或类型定义缺失导致TS类型校验不通过,结合给出的代码,可按以下步骤修复:
修复方案
- 补充ref的显式类型定义与初始值
类组件中需要先声明ref的类型并赋予初始值null,让TS确认该ref指向span元素,本身存在focus方法:
class YourComponent extends React.Component<Props, State> { // 补充ref声明 private hiddenTextRef: HTMLSpanElement | null = null; handleFocusOnText = (): void => { setTimeout(() => this.hiddenTextRef?.focus(), 500) } // 其余组件逻辑 }
- 同步测试与组件的属性配置
当前组件内的span元素没有添加测试中查询用的data-qa="test-span"属性,需要补全组件代码:
<span ref={(el) => (this.hiddenTextRef = el)} tabIndex={-1} innerHTML={hiddenContent} // 补充测试用属性 data-qa="test-span" />
- 处理测试中的定时器时序问题
组件的焦点逻辑放在了500ms的setTimeout中,而测试里的page.waitForChanges()只会等待组件状态更新、DOM重渲染完成,不会等待定时器回调执行。需要修改测试代码,等待定时器执行完毕:
如果使用jest作为测试框架,推荐用假定时器方案:
// 测试开头启用假定时器 jest.useFakeTimers() // 点击按钮 page.doc.querySelector('button').click() // 执行所有待运行的定时器回调 jest.runAllTimers() await page.waitForChanges() const spanEl = document.querySelector('[data-qa="test-span"]') expect(spanEl).not.toBeNull() // 可选补充焦点校验断言 expect(document.activeElement).toBe(spanEl) // 测试结束后恢复真实定时器 jest.useRealTimers()
如果不支持假定时器,也可以临时添加等待时长:
page.doc.querySelector('button').click() // 等待500ms以上确保定时器执行完成 await page.waitForTimeout(600) await page.waitForChanges()
- 修正渲染方法拼写
给出的组件代码中将render拼写成了rednder,如果是实际代码的错误会导致组件渲染异常,ref无法正确赋值,需要修正拼写。
内容的提问来源于stack exchange,提问作者Patrik Ondrovic
相关产品推荐
相关产品推荐

