测试React Hook状态变化时Query类reset方法报updateQuery非函数的解决
错误含义解析
TypeError: this.updateQuery is not a function 触发逻辑非常直接:调用reset()方法时,代码尝试执行this.updateQuery(),但当前实例上的this.updateQuery值为undefined,不具备可执行的函数特征,因此抛出类型错误。
问题根源非常明确:Query类的构造函数约定需传入三个参数,第三个参数会被赋值给实例的this.updateQuery属性。你在测试用例中实例化Query时只传了env和query两个参数,完全未传入第三个参数,导致实例上的updateQuery属性缺失值,变为undefined。
业务代码无报错、测试报错的原因
实际业务组件LookingGlassPanelContainer中,实例化Query的代码为:
let _query = new Query(env, query, setQuery)
这里第三个参数传入的是React useState返回的状态更新函数setQuery,是合法可执行的函数,因此reset()方法执行时不会出现函数调用错误。测试场景下跳过了这个参数传递步骤,直接断了属性的赋值链路。
不修改原有业务代码的测试调整方案
仅调整测试用例即可解决问题,可根据测试目标选择实现方式:
- 如果测试目标是单独验证
Query类本身的reset方法逻辑,直接在实例化时补传一个模拟的更新函数即可,不需要引入真实的React状态逻辑:
注意 这里的模拟函数不需要实现复杂逻辑,只要是可执行的函数即可,测试框架自带的it('handleReset', () => { // 定义测试用的模拟函数,接住reset方法传递的默认查询值 const mockUpdateQuery = jest.fn() // 按照构造函数要求传全三个参数 let _query = new Query(env, query, mockUpdateQuery) // 执行reset,不再触发函数不存在的错误 _query.reset() // 可选:增加断言验证逻辑正确性,确认reset正确调用了更新函数、传入了生成的默认query expect(mockUpdateQuery).toHaveBeenCalledWith(_query.generateDefault()) })jest.fn()即可完全满足要求。 - 如果测试目标是验证reset逻辑对组件状态的真实影响,不需要手动模拟React的状态维护流程,可以直接通过React Testing Library挂载完整的业务组件,通过页面交互触发reset行为:
// 挂载目标组件,传入测试用的env属性 render(<LookingGlassPanelContainer env={testEnvValue} />) // 找到页面上绑定了reset逻辑的交互按钮 const resetButton = screen.getByRole('button', { name: /重置/i }) // 点击触发reset fireEvent.click(resetButton) // 直接断言页面上的查询参数值已经回到默认状态即可,全程不需要手动实例化Query、手动传递setQuery函数
内容的提问来源于stack exchange,提问作者Jaimini Chothwani
相关产品推荐
相关产品推荐

