如何使用jest.spyOn配合React Testing Library测试React函数组件内部函数
问题原因与解决方案
报错根因
handleClick是TestComponent函数组件执行时内部声明的局部函数,既不是TestComponent对象的属性,也不存在于其原型链上,因此jest.spyOn(TestComponent, 'handleClick')无法找到目标函数,才会返回undefined触发报错。
解决方案
方案1:测试实际行为(更推荐,符合React Testing Library设计理念)
不用直接监听内部函数调用,转而测试点击按钮后产生的可感知效果,你的示例中handleClick会触发console打印,因此可以直接监听console.log:
it('点击按钮后触发预期打印', () => { // 劫持console.log做监听 const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {}) const { getByText } = render(<TestComponent />) fireEvent.click(getByText('Test Button')) expect(consoleSpy).toHaveBeenCalledWith('clicked!') // 测试完成后恢复原方法,避免影响其他用例 consoleSpy.mockRestore() })
方案2:抽离内部函数单独导出
如果确实需要直接监听该函数调用,可以将handleClick抽离到组件外部单独导出:
// 调整后的组件代码 import React from 'react'; const Button = (props) => ( <button onClick={props.handleClick}> {props.text}</button> ); // 抽离后单独导出 export const handleClick = () => { console.log('clicked!'); }; const TestComponent = () => { return ( <div> <Button text="Test Button" handleClick={handleClick} /> </div> ); }; export default TestComponent;
调整测试代码,监听导出的handleClick即可:
// 引入组件所在模块的所有导出内容 import * as TestCompModule from './你的组件文件路径'; it('点击按钮后调用handleClick', () => { const clickSpy = jest.spyOn(TestCompModule, 'handleClick') const { getByText } = render(<TestCompModule.default />) fireEvent.click(getByText('Test Button')) expect(clickSpy).toHaveBeenCalled() clickSpy.mockRestore() })
内容的提问来源于stack exchange,提问作者krsna
相关产品推荐
相关产品推荐

