Redux Form测试失败:TypeError - formProps.handleSubmit不是函数
这问题我之前在做Redux Form测试时也踩过坑,核心原因是你对Redux Form的handleSubmit的函数结构理解有偏差,导致测试里的模拟不符合它的实际行为。
问题根源
Redux Form提供的handleSubmit不是一个普通的事件处理函数,它是一个高阶函数:当你在组件里写formProps.handleSubmit(submitValidation)时,实际上是调用它并传入你的验证函数,它会返回一个新的函数,这个返回的函数才是真正绑定给<form>的onSubmit处理器。而你测试里直接把handleSubmit设为sinon.spy(这是一个函数,但它不会返回另一个函数),当组件尝试调用handleSubmit(submitValidation)时,得到的不是一个可执行的函数,自然就抛出TypeError了。
解决方案
你需要让测试里的handleSubmit模拟出“调用后返回函数”的行为,有两种常见的实现方式:
方式1:基础模拟(仅避免报错)
如果只是想让组件渲染不报错,不需要验证handleSubmit的调用细节,可以让handleSubmit返回一个空的spy函数:
it('will show InfoPanel', () => { const formProps = { handleSubmit: () => sinon.spy(), // 返回一个spy函数 error: {}, }; const wrapper = shallow(<UttakInfoPanel {...formProps} />); // 后续的断言逻辑 });
方式2:完整模拟(可验证调用细节)
如果需要验证handleSubmit是否被正确传入了submitValidation,或者验证表单提交时的逻辑,可以把外层和返回的函数都设为spy:
it('will show InfoPanel and handle submit correctly', () => { // 模拟submitValidation函数 const submitValidation = sinon.spy(); // 让handleSubmit是一个返回spy的spy const submitHandlerSpy = sinon.spy(); const handleSubmitSpy = sinon.spy(() => submitHandlerSpy); const formProps = { handleSubmit: handleSubmitSpy, error: {}, }; const wrapper = shallow(<UttakInfoPanel submitValidation={submitValidation} {...formProps} />); // 模拟表单提交 wrapper.find('form').simulate('submit'); // 断言handleSubmit被正确调用,参数是submitValidation expect(handleSubmitSpy.calledWith(submitValidation)).to.be.true; // 断言返回的提交处理器被触发 expect(submitHandlerSpy.called).to.be.true; });
额外提示
用shallow渲染时,要确保你传递给组件的所有必要props都已正确模拟,比如如果UttakInfoPanel还有其他依赖的Redux Form props(比如values、touched等),也需要在formProps里补充模拟,避免其他潜在的渲染错误。
内容的提问来源于stack exchange,提问作者Leff

