Jest+Enzyme测试useFormik时解构formik.values报错如何解决
报错原因
- 团队开启的测试用例间自动重置mock配置(对应Jest配置的
resetMocks: true),会在每个测试用例执行前将所有jest mock函数的实现、预设返回值全部清空,恢复为无实现的空jest.fn(),默认返回undefined。 - 之前对
useFormik的mock未生效,核心原因通常有两个:要么mock写法错误破坏了formik的模块导出,要么mock返回值设置在用例作用域外,被自动重置逻辑提前清空,导致组件渲染时调用useFormik拿到undefined,解构values属性时直接抛出类型错误。 - 线上环境运行正常是因为走的是formik库的真实
useFormik实现,会正常返回formik实例,不存在mock被清空的问题。
修复方案
- 首先在测试文件顶部正确mock formik模块,保留除
useFormik外的所有真实导出,避免<FormikProvider>等组件被误mock:
// 放在测试文件顶部的import语句之后 jest.mock('formik', () => ({ ...jest.requireActual('formik'), useFormik: jest.fn(), }))
- 将
useFormik的返回值设置逻辑放到beforeEach钩子或者单个测试用例内部,避开自动重置mock的清空时机,保证组件渲染时useFormik有符合预期的返回值:
import { shallow } from 'enzyme' import { useFormik } from 'formik' import TheComponent from './path/to/TheComponent' describe('the component name',()=>{ beforeEach(() => { // 每个用例执行前重新设置useFormik返回值,不会被重置逻辑清空 (useFormik as jest.Mock).mockReturnValue({ values: {}, // 填入组件运行需要的默认表单值即可 handleSubmit: jest.fn(), dirty: false, // 组件中从formik解构用到的其他属性都需要在这里补全,比如errors、touched、handleChange、setFieldValue等 errors: {}, touched: {}, handleChange: jest.fn(), handleBlur: jest.fn(), setFieldValue: jest.fn(), resetForm: jest.fn(), }) }) it('should render',()=>{ const wrapper = shallow(<TheComponent {...ownProps} />) expect(wrapper).toMatchSnapshot() }) })
- 不要把
useFormik的mockReturnValue设置在describe块、beforeAll钩子的顶层作用域,这类位置设置的mock返回值会在每个用例执行前被自动重置逻辑清空,无法生效。
内容的提问来源于stack exchange,提问作者NegativeFriction
相关产品推荐
相关产品推荐

