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

React Testing Library点击按钮触发Formik提交时Mock函数未调用问题

存在的问题

  • 变量名拼写错误:测试代码中导入的API模块命名是ItemAPI,但创建spy时写的是itemAPI,大小写不匹配导致mock根本没生效,原createItem方法没有被替换。
  • Input值绑定冲突:Input组件同时写了value={props.initialValues.Name}和{...props.getFieldProps("Name")},前者会把输入框的值固定为初始空值,你触发change事件修改的值根本不会同步到Formik的状态中,也不会带到onSubmit里。
  • 没有等待异步逻辑执行完成:Formik的onSubmit是异步函数,你点击提交按钮后直接同步执行断言,此时onSubmit里的异步逻辑还没跑完,自然检测不到mockCreateItem的调用。你测试直接给Button的onClick绑test能正常触发,就是因为这个调用是同步的,而异步的onSubmit内部调用需要等待执行完成才能检测到。

可行解决方案

  1. 修正测试里的API模块变量名,把jest.spyOn(itemAPI, "createItem")改为jest.spyOn(ItemAPI, "createItem")
  2. 删除Input组件上多余的value={props.initialValues.Name}属性,getFieldProps已经内置了value和onChange的绑定,不需要额外赋值初始值,否则会覆盖表单输入的内容。
  3. 测试用例改为async函数,点击提交后用waitFor包裹断言,等待异步逻辑执行完成再校验调用情况,修改后的测试代码参考:
import { waitFor } from '@testing-library/react';

describe("item form tests", () =>{
  test("add new item", async () =>{
    let mockCreateItem = jest.spyOn(ItemAPI, "createItem").mockResolvedValue({});
    let spy = jest.fn();

    render(<ItemForm test={spy}/>)
    const name = screen.getByRole('textbox',{name:"Name"})
    const submit = screen.getByRole('button',{id:"item_form_submit"})
    fireEvent.change(name,{target:{value:"Kitchen Item"}})
    fireEvent.click(submit);
    
    await waitFor(() => {
      expect(mockCreateItem).toHaveBeenCalledTimes(1)
      expect(mockCreateItem).toHaveBeenCalledWith({Name:"Kitchen Item"})
      // expect(spy).toHaveBeenCalledTimes(1)
    })
  })
})

内容的提问来源于stack exchange,提问作者Poorna

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:36:06