使用simulateError测试Error Boundary失败,是否有其他可行测试方案?
问题根源
Enzyme 的 simulateError 方法仅支持类组件实例触发,且对 React 16+ 新增的getDerivedStateFromError错误边界生命周期适配性差,你测试中使用的无状态函数子组件无法通过该方法触发错误边界的捕获逻辑。
可行测试方案
直接编写会主动抛出错误的测试子组件来验证错误边界逻辑,测试代码如下:
import { mount } from 'enzyme'; import ErrorBoundary from './ErrorBoundary'; // 测试用专用抛错组件,通过prop控制是否抛出错误 const ThrowError = ({ shouldThrow = false }) => { if (shouldThrow) throw new Error('test error'); return <div>正常渲染内容</div>; }; describe('ErrorBoundary', () => { // 测试前mock console.error,避免React错误日志污染测试输出 beforeEach(() => { jest.spyOn(console, 'error').mockImplementation(() => {}); }); // 测试结束恢复原console.error实现 afterEach(() => { console.error.mockRestore(); }); it('子组件抛错时展示错误提示、调用日志上报方法', () => { const wrapper = mount( <ErrorBoundary> <ThrowError shouldThrow={true} /> </ErrorBoundary> ); // 断言错误提示正常渲染 expect(wrapper.text()).toContain('Something went wrong, please try again or contact customer support at xxxx'); // 断言日志上报方法被正常调用 expect(jest.spyOn(wrapper.instance(), 'logErrorToServices')).toHaveBeenCalled(); }); it('子组件无错时正常渲染子组件内容', () => { const wrapper = mount( <ErrorBoundary> <ThrowError shouldThrow={false} /> </ErrorBoundary> ); expect(wrapper.text()).toContain('正常渲染内容'); }); });
注意事项
你当前的ErrorBoundary组件propTypes定义存在问题,children被声明为func类型,但测试及常规使用场景下传入的都是React元素,会触发PropTypes警告,建议修正为:
ErrorBoundary.propTypes = { children: PropTypes.node, };
如果业务确实要求children为函数类型,可忽略该修正,测试时传入返回抛错组件的函数即可。
内容的提问来源于stack exchange,提问作者Leo Garry
相关产品推荐
相关产品推荐

