测试React Logo组件快照时遭遇元素类型无效错误求助
Logo组件快照测试报错:React.createElement类型无效
尝试对Logo组件执行快照测试时触发以下错误:
React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
相关代码与环境信息
测试文件(logo.test.js)
import TestRenderer from 'react-test-renderer'; import Logo from '../components/Common/Logo'; describe('Snapshot Logo components', () => { it('Test Logo', () => { const logoComponent = TestRenderer.create(<Logo />); const logoJson = logoComponent.toJSON(); expect(logoJson).toMatchSnapshot(); }); });
Logo组件文件(../components/Common/Logo/index.js)
import React, {Component} from 'react'; import NextLink from '@material-ui/core/Link'; import LogoIcon from '../../../public/assets/icons/logo.svg'; import PATHS from '../../../router/paths'; function Logo() { return ( <NextLink href={PATHS.work}> <LogoIcon /> </NextLink> ); } export default Logo;
项目依赖(package.json)
"react": "^18.2.0", "react-test-renderer": "^18.2.0", "@material-ui/core": "^4.11.4"
系统环境
Windows 10 64-bit operating system, x64-based processor
终端报错详情
$> npx jest logo.test.js console.error Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. Check your code at index.jsx:12. at Logo 10 | return ( 11 | <NextLink href={PATHS.work}> > 12 | <LogoIcon /> | ^ 13 | </NextLink> 14 | );
问题原因与解决方案
问题根源
Jest默认不会将SVG文件转换为React组件,直接导入SVG时会被当作普通对象处理,导致<LogoIcon />无法被识别为合法的React组件类型。
解决方法
方法1:配置Jest模拟SVG文件
- 在项目根目录创建
jest.config.js,添加SVG文件映射规则:
module.exports = { moduleNameMapper: { '\\.svg$': '<rootDir>/__mocks__/svgMock.js', }, };
- 在根目录创建
__mocks__/svgMock.js文件,返回一个空的React组件作为SVG的模拟:
import React from 'react'; const SvgMock = () => <span />; export default SvgMock;
方法2:使用@svgr/jest转换SVG为组件
- 安装依赖:
npm install --save-dev @svgr/jest
- 修改
jest.config.js,配置SVG使用@svgr/jest处理:
module.exports = { moduleNameMapper: { '\\.svg$': '@svgr/jest', }, };
这种方式会将SVG转为真实的React组件,快照中会保留SVG的结构细节。
方法3:改用img标签加载SVG
如果不需要在快照中保留SVG的结构,可以直接将SVG作为图片资源导入:
import React from 'react'; import NextLink from '@material-ui/core/Link'; import logoSrc from '../../../public/assets/icons/logo.svg'; import PATHS from '../../../router/paths'; function Logo() { return ( <NextLink href={PATHS.work}> <img src={logoSrc} alt="Logo" /> </NextLink> ); } export default Logo;
内容的提问来源于stack exchange,提问作者A.B
相关产品推荐
相关产品推荐

