Jest测试中handleClickIconEye方法报错(无法找到对应节点的window对象),同组件handleClickNewBill测试正常的问题排查
问题分析与解决方案
你的第二个测试用例出现 Unable to find the "window" object for the given node 错误,主要有几个关键原因,我们逐个拆解解决:
1. 错误的点击目标(最直接原因)
你的测试代码里写了:
userEvent.click(handleClickIconEye1)
这里你错误地点击了jest mock函数,而不是实际的DOM元素 icons!userEvent.click 要求传入真实的DOM节点,传入函数会直接导致找不到关联window对象的节点,引发报错。
正确写法应该是点击图标元素本身:
userEvent.click(icons)
2. jQuery与Bootstrap Modal的测试环境缺失
handleClickIconEye 方法依赖了jQuery的 $ 语法和Bootstrap的 modal() 方法,但Jest的jsdom环境默认没有引入这些依赖:
- 若未在测试环境中引入jQuery/Bootstrap,调用
$('#modaleFile').modal('show')时会因为找不到对应API而报错; - 另外,如果你的
Actions(url)生成的HTML里没有包含#modaleFile模态框元素,jQuery无法定位到该节点,也会触发相关错误。
解决办法:
方法一:模拟jQuery和Bootstrap的modal方法
在你的 setup-jest.js 中添加以下代码,模拟依赖的API行为:
import $ from 'jquery'; global.$ = $; // 模拟Bootstrap的modal方法,避免真实调用引发的环境问题 $.fn.modal = jest.fn();
这样既可以避免环境缺失的错误,还能验证 modal('show') 是否被正确调用。
方法二:确保测试页面包含模态框元素
设置 document.body.innerHTML 时,要手动加入模态框的基础结构:
const html = ` ${Actions(url)} <!-- 加入模态框基础结构 --> <div class="modal fade" id="modaleFile" tabindex="-1"> <div class="modal-body"></div> </div> `; document.body.innerHTML = html;
3. 多图标场景下的元素获取问题
如果页面中有多个 icon-eye 元素,使用 screen.getByTestId('icon-eye') 会抛出「找到多个匹配元素」的错误,此时应该用 screen.getAllByTestId('icon-eye')[0] 获取第一个图标,或者根据测试场景选择对应元素。
修正后的测试代码示例
test("Then i click on Action icon modal should be open", ()=>{ const onNavigate=(pathname)=>{ document.body.innerHTML=ROUTES({pathname}) } Object.defineProperty(window,'localStorage',{value:localStorageMock}) window.localStorage.setItem('user',JSON.stringify({ type:'Employee' })) const bills=new Bills({ document,onNavigate,firestore:null,localStorage:window.localStorage}) const url = '/fake_url' // 确保页面包含模态框结构 const html= ` ${Actions(url)} <div id="modaleFile" class="modal"> <div class="modal-body"></div> </div> ` document.body.innerHTML=html // 获取目标图标(单个用getByTestId,多个用getAllByTestId) const icon=screen.getByTestId('icon-eye') const handleClickIconEyeMock=jest.fn(bills.handleClickIconEye) icon.addEventListener('click', (e) => handleClickIconEyeMock(e.target)) userEvent.click(icon) // 验证mock函数被调用 expect(handleClickIconEyeMock).toHaveBeenCalled() // 验证modal方法被触发(如果模拟了jQuery的modal) expect($('#modaleFile').modal).toHaveBeenCalledWith('show') })
为什么第一个测试用例正常运行?
第一个测试的逻辑非常简单:仅涉及点击按钮调用 onNavigate,既没有依赖jQuery/Bootstrap这类外部API,也没有出现「点击mock函数」的低级错误,所以可以正常通过。
内容的提问来源于stack exchange,提问作者Ghaith Diab
相关产品推荐
相关产品推荐

