如何在React测试中调用Context Provider中声明的showModal函数?
在测试中访问Context Provider内的showModal函数
我尝试测试Context Provider中声明的showModal函数:
export const ModalProvider = ({ children }: ProviderProps) => { const [isOpen, setIsOpen] = useState<boolean>(false); const [titleText, setTitleText] = useState<string>(''); const [contentText, setContentText] = useState<string>(''); const [hideCloseButton, setHideCloseButton] = useState<boolean>(false); const showModal: ShowModalProps = useCallback((title, content, hideCloseButton) => { setIsOpen(true); setTitleText(title); setContentText(content); setHideCloseButton(hideCloseButton); }, []); const closeModal = () => { setIsOpen(false); }; return ( <ModalContext.Provider value={{ isOpen, setIsOpen, showModal, closeModal, titleText, contentText, hideCloseButton }} > {children} </ModalContext.Provider> ); };
我编写了如下测试代码,结果遇到“showModal未定义”的错误,明明已经用ModalProvider包裹了页面,不清楚该如何在测试中访问并调用这个函数:
describe('Modal testing', () => { it(`Should render popup modal`, () => { render( <ModalProvider> <HomePage /> </ModalProvider> ); showModal('TEST', 'TEST Text', false); const errorMessage = screen.getByText('TEST Text'); expect(errorMessage).toBeDefined(); }); });
解决方案
方法1:创建测试组件获取Context并调用函数
showModal属于Context内部方法,只能在React组件树中通过useContext获取。可以在测试中定义一个临时组件,用于获取Context并调用showModal:
describe('Modal testing', () => { it(`Should render popup modal`, () => { const TestTrigger = () => { const { showModal } = useContext(ModalContext); useEffect(() => { showModal('TEST', 'TEST Text', false); }, [showModal]); return null; }; render( <ModalProvider> <TestTrigger /> <HomePage /> </ModalProvider> ); const modalContent = screen.getByText('TEST Text'); expect(modalContent).toBeInTheDocument(); }); });
方法2:模拟真实用户操作触发函数
如果showModal是在HomePage中通过用户交互(比如点击按钮)触发的,直接模拟这个操作更贴合真实业务场景:
describe('Modal testing', () => { it(`Should render popup modal when trigger is clicked`, () => { render( <ModalProvider> <HomePage /> </ModalProvider> ); // 假设HomePage里有触发弹窗的按钮,文本为"打开弹窗" fireEvent.click(screen.getByText('打开弹窗')); const modalContent = screen.getByText('TEST Text'); expect(modalContent).toBeInTheDocument(); }); });
方法3:从render结果中手动提取Context值
借助React Testing Library的render返回结果,通过临时组件提取Context:
describe('Modal testing', () => { it(`Should render popup modal`, () => { const { container } = render( <ModalProvider> <HomePage /> </ModalProvider> ); let contextValue; const TempComponent = () => { contextValue = useContext(ModalContext); return null; }; render(<TempComponent />, { container }); contextValue.showModal('TEST', 'TEST Text', false); const modalContent = screen.getByText('TEST Text'); expect(modalContent).toBeInTheDocument(); }); });
问题根源
测试代码的顶层作用域不属于React组件树,无法直接访问Context内部的showModal函数,必须在组件内部通过useContext(ModalContext)获取后才能调用。
内容的提问来源于stack exchange,提问作者Alex T
相关产品推荐
相关产品推荐

