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
相关产品推荐
相关产品推荐

