使用react-testing-library与jest测试组件prop函数是否被调用
首先纠正你的猜测:重渲染导致onSubmit实例变化的情况不存在。你在测试用例中声明的onSubmit = jest.fn()在整个测试执行周期内没有被重新赋值,组件每次重渲染时接收的都是同一个函数实例,不需要使用spyOn来处理实例一致性问题。
问题通常出在测试代码的写法上,常见原因有两个:
- 没有从
render方法的返回值中解构查询方法,直接调用全局的getByText/getByRole可能命中其他渲染实例的元素,导致事件没有触发到目标组件的按钮上 - 手动包裹
act加上React状态批处理的特性,导致断言执行时onSubmit回调还没有被触发
你可以直接使用修正后的测试代码:
it('submits the name on save', async () => { const name = 'Some name' const updatedName = 'New name' const onSubmit = jest.fn() // 从render返回值解构查询方法,限定查询范围为当前组件 const { getByText, getByRole } = render( <EditableName name={name} onSubmit={onSubmit} /> ) // fireEvent内部已经封装了act逻辑,不需要手动包裹 fireEvent.click(getByText('Edit')) fireEvent.change(getByRole('input'), { target: { value: updatedName } }) fireEvent.click(getByText('Save')) // 用waitFor确保所有回调执行完成后再做断言 await waitFor(() => { expect(onSubmit).toBeCalledTimes(1) // 可选:增加参数校验,验证传参是否符合预期 expect(onSubmit).toBeCalledWith({ name: updatedName }) }) })
如果修改后问题仍然存在,可以排查测试配置中是否有全局的mock重置逻辑(比如beforeEach(() => jest.clearAllMocks())),确保你的onSubmit mock函数是在重置逻辑执行之后声明的,避免调用记录被意外清空。
关于spyOn的说明
spyOn仅适用于监听已有对象上的方法调用,比如监听模块导出方法、类实例方法的场景。你当前场景下自己创建的mock函数直接传入组件即可正常监听调用,不需要额外用spyOn包装。
内容的提问来源于stack exchange,提问作者ongelo
相关产品推荐
相关产品推荐

