使用Jest和Enzyme测试React组件按钮点击时嵌套函数是否被调用
问题修复方案
首先先修正原组件的两处语法问题,否则组件无法正常运行:
class MyComponent extends React.Component { handleButton () { console.warn('Clicked!') this.context.anotherFunction() } render () { return ( <div> My Component {/* 修正1:class改className,绑定this.handleButton而不是直接写handleButton */} <button className='my-button' onClick={this.handleButton}>My Button</button> </div> ) } }
你的测试代码核心问题
- 手动覆盖了
handleButton实例方法,原有调用this.context.anotherFunction的逻辑被你替换成了空逻辑,自然不会触发context函数 - 断言变量名和实际mock的变量不匹配:你mock的是context下的
anotherFunction,断言却写了context.showModal,showCancelModal也没有任何定义 - 直接给实例context赋值的方式不够稳定,推荐在shallow渲染时直接传入context参数
方案1:推荐:不重写handleButton,直接测试原生逻辑
这种方案最贴合实际运行场景,验证组件原生逻辑是否符合预期:
test.only('should test MyComponent button', () => { // 提前定义mock的context函数 const mockAnotherFunction = jest.fn() // shallow渲染时直接注入context const wrapper = shallow(<MyComponent {...props} />, { context: { anotherFunction: mockAnotherFunction } }) // 模拟点击按钮 wrapper.find('.my-button').simulate('click') // 断言context函数被调用 expect(mockAnotherFunction).toHaveBeenCalled() })
方案2:如果你确实需要自定义mock handleButton,同时触发anotherFunction
直接在你重写的handleButton里调用你定义的mock函数即可:
test.only('should test MyComponent button', () => { const mockAnotherFunction = jest.fn() const mockHandleButton = jest.fn(() => { // 这里调用你mock的context函数 mockAnotherFunction() }) const wrapper = shallow(<MyComponent {...props} />, { context: { anotherFunction: mockAnotherFunction } }) // 替换原handleButton为你的mock版本 wrapper.instance().handleButton = mockHandleButton // 要调用forceUpdate更新绑定的事件 wrapper.instance().forceUpdate() wrapper.find('.my-button').simulate('click') // 断言两个函数都被调用 expect(mockHandleButton).toHaveBeenCalled() expect(mockAnotherFunction).toHaveBeenCalled() })
注意:替换实例方法后必须调用
forceUpdate(),否则按钮绑定的还是原来的handleButton方法,你的mock不会生效。
内容的提问来源于stack exchange,提问作者theJuls
相关产品推荐
相关产品推荐

