@testing-library/react如何捕获测试Hook抛出的错误
此前疑似已废弃的 react-hooks-testing-library,会返回被测Hook抛出的所有错误。
或许是我个人理解有偏差,但目前主库 @testing-library/react 内置的Hook测试实现似乎丢失了这一特性。我自行设计了可捕获Hook抛出错误的测试方案,具体如下:
测试用例示例
import { safeRenderHook } from './safeRenderHook'; function useFail() { throw 'fail'; } function useSucceed() { return 'success'; } it('should fail', () => { const { result, error } = safeRenderHook(() => useFail()); expect(error.current).toEqual('fail'); expect(result.current).toBeUndefined(); }); it('should succeed', () => { const { result, error } = safeRenderHook(() => useSucceed()); expect(result.current).toEqual('success'); expect(error.current).toBeUndefined(); });
工具参考实现
import { render } from '@testing-library/react'; import React from 'react'; /** * 自定义Hook渲染工具,是原生`renderHook()`的变体,返回结构为`{ result, error }` * 其中`error`字段会存储Hook执行时抛出的所有错误,其余行为和原生`renderHook()`完全一致 * * 用法示例: * const useFail = () => Promise.reject('fail!'); * it('should fail', () => { * const { error } = safeRenderHook(() => useFail()); * expect(error).toEqual('fail!'); * }) */ export function safeRenderHook(renderCallback, options = {}) { const { initialProps = [], wrapper } = options; const result = React.createRef(); const error = React.createRef(); function TestComponent({ hookProps }) { let pendingError; let pendingResult; try { pendingResult = renderCallback(...hookProps); } catch (err) { pendingError = err; } React.useEffect(() => { result.current = pendingResult; error.current = pendingError; }); return null; } const { rerender: baseRerender, unmount } = render(<TestComponent hookProps={initialProps} />, { wrapper }); function rerender(rerenderCallbackProps) { return baseRerender(<TestComponent hookProps={rerenderCallbackProps} />); } return { result, error, rerender, unmount }; }
注意:由于该实现本质上会拦截吞掉Hook抛出的错误,使用时必须显式校验返回的
error值,避免遗漏错误场景的断言。
补充说明:我还实现了该工具的TypeScript类型安全版本,若有需要可提供——考虑到类型注解会提升示例的阅读门槛,上述示例中未展示相关类型代码。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

