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

React表单测试:如何断言handleSubmit方法与props.post方法被调用

验证Parameters表单的handleSubmit和props.post调用

我来帮你搞定这个测试验证的问题,要确认点击"Salva"按钮时handleSubmit被触发,且props.post(对应Redux的dispatch动作)被正确调用,你可以按照下面的步骤调整测试代码:

1. 修正Mock Store的初始状态

首先,你的initialState里不需要包含post方法——这是mapDispatchToProps负责映射的逻辑,不属于Redux state的范畴。正确的初始状态只需要保留parameters模块的isLoading即可:

const initialState = {
  parameters: {
    isLoading: false,
  },
}

2. 验证Redux Action是否被正确Dispatch

点击保存按钮后,你可以通过mock store的getActions()方法获取所有被dispatch的动作,然后验证动作的类型和payload是否符合预期:

// 点击保存按钮后
fireEvent.click(screen.getByText(/salva/i))

// 获取所有被dispatch的actions
const dispatchedActions = store.getActions()

// 验证动作数量(确保只有一个post动作被触发)
expect(dispatchedActions.length).toBe(1)

// 验证动作类型(替换成你实际定义的action类型,比如'PARAMETERS_POST')
const postAction = dispatchedActions[0]
expect(postAction.type).toBe(parametersActions.post.type)

// 验证payload是否和输入的测试值一致
expect(postAction.payload).toEqual({
  birthdate: '1990-12-31',
  height: '170'
})

3. 间接验证handleSubmit被调用

因为handleSubmit是组件内部的私有函数,没办法直接通过测试框架监听它的调用。不过我们可以通过两种间接方式证明它被执行了:

  • 既然已经验证了Redux action被正确dispatch,而action的dispatch是在handleSubmit内部触发的,这就间接证明了handleSubmit被执行了;
  • 如果你需要更直接的验证,可以把handleSubmit抽成组件外部的独立函数,然后用jest.spyOn监听它的调用,但这需要修改组件代码。大多数情况下,通过验证最终的副作用(比如Redux action)来测试组件行为是更合理的做法。

完整修改后的测试代码

import { render, screen, fireEvent } from '@testing-library/react'
import thunk from 'redux-thunk'
import configureMockStore from 'redux-mock-store'
import Parameters from '../../../presentationals/forms/Parameters'
import { actions as parametersActions } from '../../../actions/ParametersActions' // 修正导入的命名

describe('Parameters form', () => {
  it('Can store new parameters', async () => {
    const middlewares = [thunk]
    const mockStore = configureMockStore(middlewares)
    const initialState = {
      parameters: {
        isLoading: false,
      },
    }
    const store = mockStore(initialState)

    render(<Parameters store={store} />)

    // 验证表单元素存在
    const birthdateLabel = screen.getByText(/nascita/i)
    expect(birthdateLabel).toBeInTheDocument()

    const heightLabel = screen.getByText(/altezza/i)
    expect(heightLabel).toBeInTheDocument()

    // 输入测试值
    fireEvent.change(screen.getByLabelText(/nascita/i), { target: {value: '1990-12-31'} })
    fireEvent.change(screen.getByLabelText(/altezza/i), { target: {value: '170'} })

    // 点击保存按钮
    fireEvent.click(screen.getByText(/salva/i))

    // 验证Redux action是否正确dispatch
    const dispatchedActions = store.getActions()
    expect(dispatchedActions.length).toBe(1)

    const postAction = dispatchedActions[0]
    expect(postAction.type).toBe(parametersActions.post.type) // 替换成你实际的action类型字符串也可以
    expect(postAction.payload).toEqual({
      birthdate: '1990-12-31',
      height: '170'
    })
  })
})

额外提示

  • 注意你导入parametersActions的时候,之前写的是import { action as parametersActions },应该修正为import { actions as parametersActions }(或者根据你的实际导出结构调整,比如如果是单个action导出,可能是import { post } from ...);
  • 如果你的parametersActions.post是一个action创建函数,那么它返回的action对象里的type需要和测试中断言的完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 18:37:43