You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 00:12:53