使用Jest和RTL测试组件时如何解决SVG渲染错误?
解决Jest+RTL测试Next.js组件时SVG作为组件渲染的错误
这个错误的核心原因是:Next.js默认将SVG导入为静态资源路径(字符串),但你把它当作React组件使用。开发环境可能通过webpack配置了SVGR支持,但测试环境Jest没有对应的处理逻辑,导致渲染时拿到的是字符串/对象而非组件类型。
下面提供两种可行的修复方案:
方案一:Mock SVG模块(快速解决测试问题)
直接在Jest中把SVG文件mock成基础的React SVG组件,不需要修改项目的webpack配置:
- 在项目根目录创建
__mocks__/svgMock.js文件:
import React from 'react'; const SvgMock = React.forwardRef((props, ref) => ( <svg ref={ref} {...props} /> )); export default SvgMock;
- 修改
jest.config.js,添加模块映射:
module.exports = { // 保留原有配置 moduleNameMapper: { // 新增SVG映射 '\\.svg$': '<rootDir>/__mocks__/svgMock.js', }, };
或者,也可以在单个测试文件顶部临时mock:
// 在你的SearchHeader测试文件开头添加 jest.mock('public/icon/prevArrow.svg', () => ({ default: () => <svg /> })); jest.mock('public/icon/search.svg', () => ({ default: () => <svg /> }));
方案二:配置SVGR支持SVG组件导入(适配开发+测试环境)
如果需要在开发环境也直接把SVG当作组件使用,可以配置Next.js的webpack支持SVGR,同时同步Jest的处理逻辑:
- 安装SVGR依赖:
npm install --save-dev @svgr/webpack @svgr/jest
- 修改
next.config.js,添加SVG处理规则:
module.exports = { webpack(config) { config.module.rules.push({ test: /\.svg$/i, issuer: /\.[jt]sx?$/, // 只处理js/tsx文件中导入的SVG use: ['@svgr/webpack'], }); return config; }, };
- 修改组件中的SVG导入方式(推荐用ReactComponent别名,避免混淆静态资源):
// 替换原有导入 import { ReactComponent as Prev } from "public/icon/prevArrow.svg"; import { ReactComponent as Search } from "public/icon/search.svg";
- 修改
jest.config.js,添加SVG的transform规则:
module.exports = { // 保留原有配置 transform: { // 新增SVG处理 '\\.svg$': '@svgr/jest', }, };
完成以上配置后,不管是开发环境还是测试环境,都可以正常将SVG作为React组件渲染。
内容的提问来源于stack exchange,提问作者김정수
相关产品推荐
相关产品推荐

