如何测试React Router Dom中<Link />组件的URL跳转功能
现有代码问题说明
- 混用了Enzyme和React Testing Library两套测试工具的能力:你用
mountWithTheme渲染的内容仅在Enzyme的wrapper实例中可查询,React Testing Library的screen无法捕获到这部分渲染结果,所以userEvent.click的操作完全无效。 - 元素查询逻辑错误:你要点击的按钮文本是
Reset filters,并不是offerings,screen.getByText(/offerings/i)根本找不到目标元素。 - 使用
BrowserRouter做路由测试无法直接获取路由状态,不适合单元测试场景。 Link组件本身的跳转逻辑已经由react-router-dom官方覆盖了完整测试,不需要重复验证点击触发跳转的原生能力,优先选择更轻量的测试方案即可。
正确实现方案
方案1:属性验证(推荐,性能最高)
只需要验证Link组件传入的to属性符合预期即可,不需要模拟点击操作:
it('should go to /offerings when the button is clicked when logged in', () => { const wrapper = mountWithTheme( <Provider store={configureMockStore({ user: { userState: { loggedIn: true, }, }, })} > <BrowserRouter> <MarketplaceEmptyState resetFilter={resetFilter} /> </BrowserRouter> </Provider> ); wrapper.find('MarketplaceEmptyState').setState({ allStatusFetched: true, }); expect( wrapper.find('[data-cy="empty-state-filter-copy"]').first().text() ).toEqual(`Please reset the filters.`); // 直接验证Link的to属性是否正确 expect(wrapper.find('Link').prop('to')).toBe('/offerings'); });
方案2:模拟点击验证跳转(需要完整验证交互场景时使用)
用MemoryRouter代替BrowserRouter,可以直接监听路由变化:
import { MemoryRouter } from 'react-router-dom'; it('should go to /offerings when the button is clicked when logged in', () => { const historyEntries = ['/current-path']; const wrapper = mountWithTheme( <Provider store={configureMockStore({ user: { userState: { loggedIn: true, }, }, })} > <MemoryRouter initialEntries={historyEntries} initialIndex={0}> <MarketplaceEmptyState resetFilter={resetFilter} /> </MemoryRouter> </Provider> ); wrapper.find('MarketplaceEmptyState').setState({ allStatusFetched: true, }); expect( wrapper.find('[data-cy="empty-state-filter-copy"]').first().text() ).toEqual(`Please reset the filters.`); // 点击按钮 wrapper.find('button[trackingId="reset-filters"]').simulate('click', { button: 0 }); // 验证路由已跳转 expect(wrapper.find(MemoryRouter).prop('history').location.pathname).toBe('/offerings'); });
内容的提问来源于stack exchange,提问作者jarwin
相关产品推荐
相关产品推荐

