React面包屑组件测试:点击a标签后如何验证是否渲染对应组件
解决方案
你需要根据项目使用的跳转方式选择对应测试逻辑:
情况1:使用原生<a>标签跳转(当前你代码中的写法)
原生a标签点击会触发浏览器全局跳转,你可以通过拦截监听window.location的变化验证跳转路径是否正确,如果需要验证对应组件渲染,需要配合完整路由测试环境:
describe("BreadCrumb Component", () => { let shallowWrapper: ShallowWrapper; let breadCrumbWrapper: ReactWrapper; // 保存原始location,避免测试污染其他用例 const originalLocation = window.location; beforeEach(() => { // 用jest mock重写location delete window.location; window.location = new URL("http://localhost") as any; }); afterEach(() => { window.location = originalLocation; }); it('should be a div Component and jump to home correctly', () => { shallowWrapper = shallow(<BreadCrumb ></BreadCrumb>); expect(shallowWrapper.type()).toBe('div') breadCrumbWrapper = mount(<BreadCrumb ></BreadCrumb>); const breadcrumbvalues = breadCrumbWrapper.find('nav').find('ol').find('li').map(col => col.text()); expect(breadcrumbvalues).toHaveLength(2); expect(breadcrumbvalues[0]).toEqual("Home"); expect(breadcrumbvalues[1]).toEqual("activepage"); // 拦截a标签的默认跳转行为,避免jsdom环境报错 const aTag = breadCrumbWrapper.find('a[href="/home"]'); aTag.simulate('click', { preventDefault: () => {} }); // 验证跳转路径符合预期 expect(aTag.prop('href')).toBe('/home'); // 如需验证路径对应组件渲染,将整个路由配置挂载到测试环境即可 // 示例:假设路由配置为 /home 对应Home组件 // const appWrapper = mount(<BrowserRouter><App /></BrowserRouter>); // appWrapper.find('a[href="/home"]').simulate('click', { preventDefault: () => {} }); // expect(appWrapper.find(Home)).toHaveLength(1); }) })
情况2:项目使用React Router等单页路由库(单页应用常规写法)
建议先将原生<a>替换为路由库的Link组件避免页面刷新,测试时用MemoryRouter包裹组件即可验证路由跳转和对应组件渲染:
面包屑组件修改示例
// 引入路由Link组件 import { Link } from 'react-router-dom'; return ( <div> <nav aria-label="breadcrumb"> <ol className="breadcrumb"> <li className="breadcrumb-item"><Link to="/home">Home</Link></li> <li className="breadcrumb-item active" aria-current="page">activepage</li> </ol> </nav> </div> )
对应测试用例
import { MemoryRouter, Routes, Route } from 'react-router-dom'; // 引入你/home路径对应的业务组件 import Home from './Home'; describe("BreadCrumb Component", () => { let shallowWrapper: ShallowWrapper; let breadCrumbWrapper: ReactWrapper; it('should be a div Component and render Home component after jump', () => { shallowWrapper = shallow(<BreadCrumb ></BreadCrumb>); expect(shallowWrapper.type()).toBe('div') // 用MemoryRouter包裹,配置测试路由对应关系 breadCrumbWrapper = mount( <MemoryRouter initialEntries={['/current-page']}> <Routes> <Route path="/current-page" element={<BreadCrumb />} /> <Route path="/home" element={<Home />} /> </Routes> </MemoryRouter> ); const breadcrumbvalues = breadCrumbWrapper.find('nav').find('ol').find('li').map(col => col.text()); expect(breadcrumbvalues).toHaveLength(2); expect(breadcrumbvalues[0]).toEqual("Home"); expect(breadcrumbvalues[1]).toEqual("activepage"); // 点击Home链接 breadCrumbWrapper.find('a[href="/home"]').simulate('click', { preventDefault: () => {} }); // 验证Home组件成功渲染 expect(breadCrumbWrapper.find(Home)).toHaveLength(1); }) })
内容的提问来源于stack exchange,提问作者code_block
相关产品推荐
相关产品推荐

