React(Vitest)单元测试报错:connect ECONNREFUSED ::1:3000求助
问题详情
测试时出现如下报错:
stderr | unknown test
Error: Error: connect ECONNREFUSED ::1:3000
at Object.dispatchError (E:\customer-dashboard\node_modules\jsdom\lib\jsdom\living\xhr\xhr-utils.js:63:19)
at Request. (E:\customer-dashboard\node_modules\jsdom\lib\jsdom\living\xhr\XMLHttpRequest-impl.js:655:18)
at Request.emit (node:events:525:35)
at ClientRequest. (E:\customer-dashboard\node_modules\jsdom\lib\jsdom\living\helpers\http-request.js:127:14)
at ClientRequest.emit (node:events:513:28)
at Socket.socketErrorListener (node:_http_client:494:9)
at Socket.emit (node:events:513:28)
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at processTicksAndRejections (node:internal/process/task_queues:82:21) undefined
使用的ReactSVG组件代码:
<ReactSVG src='svg/heart_fill.svg' beforeInjection={(svg) => { svg.setAttribute('style', `width: ${width}; height: ${height}`); }} onClick={(e) => onClick && onClick(e)} {...props} />
本地SVG路径采用src/assets/svg/s_cart.svg形式,尝试Mock路径后问题仍未解决。
解决方案
1. Mock ReactSVG组件的资源加载行为
jsdom环境下,ReactSVG会对相对路径的src发起真实HTTP请求,而测试时本地未启动3000端口服务,导致连接拒绝。直接Mock整个ReactSVG组件,避免真实请求:
import ReactSVG from 'react-svg'; vi.mock('react-svg', () => ({ default: vi.fn(({ ...props }) => { // 返回模拟的SVG容器元素,替代真实加载逻辑 return <div data-testid="mock-svg" {...props} />; }), }));
2. 改用导入方式引用SVG并Mock文件
先调整组件代码,通过import导入SVG文件而非直接写路径字符串:
import HeartFillSvg from 'src/assets/svg/heart_fill.svg'; <ReactSVG src={HeartFillSvg} beforeInjection={(svg) => { svg.setAttribute('style', `width: ${width}; height: ${height}`); }} onClick={(e) => onClick && onClick(e)} {...props} />
然后在vitest.config.js中配置SVG文件的Mock规则:
export default defineConfig({ test: { environment: 'jsdom', moduleNameMapper: { '\\.svg$': '<rootDir>/__mocks__/svgMock.js', }, }, });
创建__mocks__/svgMock.js文件:
export default 'mock-svg-resource';
3. 配置jsdom的基础URL
确保jsdom环境的基础URL与应用预期一致,避免路径解析错误:
import { JSDOM } from 'jsdom'; const dom = new JSDOM('<!DOCTYPE html>', { url: 'http://localhost:3000', }); global.document = dom.window.document; global.window = dom.window;
核心原因
jsdom环境中,ReactSVG的src属性如果是相对路径,会被解析为http://localhost:3000/xxx的HTTP请求,而测试过程中本地没有运行对应端口的服务,因此触发ECONNREFUSED错误。通过Mock拦截请求或调整SVG引用方式,即可解决该问题。
内容的提问来源于stack exchange,提问作者BCK

