Material UI本地Jest测试报错:_capitalize.default不是函数
capitalize is not a function错误 我之前碰到过几乎一模一样的问题,这个报错本质上是测试环境下模块解析/转译不兼容导致的,尤其是Material-UI的ES模块和Jest默认配置之间的冲突。结合你的情况,给你几个具体的排查和解决步骤:
1. 调整Jest的transformIgnorePatterns配置
Jest默认会忽略对node_modules目录下文件的转译,但Material-UI的部分包(比如@material-ui/core)是用ES模块编写的,在测试环境下需要被转译才能正确解析默认导出。
修改你的jest.config.js(或者在package.json的jest字段里),把Material-UI相关包排除在忽略列表外:
module.exports = { // 其他配置... transformIgnorePatterns: [ '/node_modules/(?!@material-ui/core|@material-ui/icons|@material-ui/lab|@material-ui/pickers)/', ], };
这个配置的意思是:除了指定的Material-UI包之外,其他node_modules里的文件都跳过转译。
2. 检查Babel配置的兼容性
确保你的Babel配置能正确处理React和ES模块的转译,尤其是针对Node环境的设置:
在babel.config.js或者.babelrc里添加:
{ "presets": [ ["@babel/preset-env", { "targets": { "node": "current" } }], "@babel/preset-react" ] }
这个配置会让Babel根据当前Node版本转译代码,避免测试环境下的语法兼容问题。
3. 确认Enzyme适配器与React版本匹配
你用的是React 16.9.0,对应的Enzyme适配器应该是enzyme-adapter-react-16,并且要在测试启动文件(比如src/setupTests.js)里正确配置:
import { configure } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; configure({ adapter: new Adapter() });
如果适配器版本不匹配,也可能导致虚拟DOM挂载时的奇怪错误。
4. 验证mountWithIntl的实现是否正确
检查你的intlHelper.js里的mountWithIntl函数,确保它同时正确包裹了IntlProvider和ThemeProvider,并且传递了有效的主题配置:
import { mount } from 'enzyme'; import { IntlProvider } from 'react-intl'; import { ThemeProvider } from '@material-ui/core/styles'; import yourCustomTheme from '../../src/path-to-your-theme'; export const mountWithIntl = (component) => { return mount( <IntlProvider locale="en" defaultLocale="en"> <ThemeProvider theme={yourCustomTheme}> {component} </ThemeProvider> </IntlProvider> ); };
如果主题配置有问题,也可能间接导致Material-UI组件内部的函数调用失败。
5. 临时排查:Mock capitalize函数
如果上面的方法都没解决,可以尝试在测试文件里临时Mock这个函数,确认是否是模块导入的问题:
jest.mock('@material-ui/core/utils/capitalize', () => ({ default: (str) => str.charAt(0).toUpperCase() + str.slice(1), }));
这只是临时方案,核心还是要解决转译/解析的根本问题。
按照这个顺序排查,大概率能解决你遇到的问题——我当时就是通过调整Jest的transformIgnorePatterns解决的。
内容的提问来源于stack exchange,提问作者Constantin M

