You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

未使用setImmediate却触发ReferenceError错误的原因排查

问题排查与解决方案

错误原因分析

这个ReferenceError: setImmediate is not defined错误,本质是测试环境(jsdom + Jest)与WebSocket相关依赖的兼容性问题:

  • 你的App组件在渲染时大概率初始化了WebSocket连接,而jsdom没有原生WebSocket实现,依赖了xmlhttprequest-ssl作为polyfill
  • 该polyfill使用了Node.js的setImmediate方法,但Create React App的Jest测试环境没有全局暴露这个方法
  • 测试时无后端WebSocket服务,连接失败触发错误流程,最终暴露了这个未定义方法的问题

具体解决办法

方法1:Mock WebSocket对象(最推荐)

既然你的测试只需要验证组件渲染,不需要实际的WebSocket连接,直接在测试文件中mock全局WebSocket,避免触发真实连接逻辑:

import React from 'react';
import { render } from '@testing-library/react';
import App from './App';

// 全局mock WebSocket,阻止真实连接
global.WebSocket = jest.fn(() => ({
  onopen: jest.fn(),
  onmessage: jest.fn(),
  onclose: jest.fn(),
  send: jest.fn(),
  close: jest.fn()
}));

test('renders the app', async () => {
  window.HTMLElement.prototype.scrollIntoView = function() {};

  const {container} = await render(<App />);
  expect(container.querySelector('h1')).toHaveTextContent('Welcome to ChitChat')
});

方法2:添加setImmediate的polyfill

如果需要保留部分WebSocket逻辑,可在测试环境中补全setImmediate定义,在测试文件开头或项目根目录的src/setupTests.js中添加:

// 给测试环境添加setImmediate的polyfill
global.setImmediate = global.setImmediate || ((callback) => setTimeout(callback, 0));

方法3:修改组件逻辑适配测试

将WebSocket的初始化逻辑抽离,支持测试时注入模拟实例,比如:

// App.js中抽离WebSocket创建逻辑
export const createWebSocket = () => new WebSocket('ws://your-url');

function App() {
  const ws = useMemo(() => createWebSocket(), []);
  // ...其他逻辑
}

// 测试时替换createWebSocket
import { createWebSocket } from './App';

jest.mock('./App', () => ({
  ...jest.requireActual('./App'),
  createWebSocket: jest.fn(() => ({ /* mock实例 */ }))
}));

内容的提问来源于stack exchange,提问作者Animus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 05:45:38