React+TypeScript组件测试报错:无法解构useContext的basename属性
问题分析
这个错误和你传递props的方式无关,根源是Login组件内的<Link>组件依赖react-router的路由上下文才能运行。当你直接在测试中渲染Login时,没有提供路由上下文(比如<BrowserRouter>或<MemoryRouter>),导致Link调用useContext获取路由数据时得到null,进而无法解构basename属性。
解决方案
在测试中用react-router-dom提供的<MemoryRouter>(测试环境首选,无需真实URL)包裹Login组件,为Link提供必要的路由上下文:
- 先在测试文件中导入
MemoryRouter:
import { MemoryRouter } from 'react-router-dom';
- 修改渲染逻辑,用MemoryRouter包裹Login:
describe('Login unit tests', () => { it('renders to screen', () => { const loginProps = { handleSubmit: (e: MouseEvent<HTMLButtonElement>) => Promise.resolve(console.log('handleSubmit')), usernameProps: { value: "", placeholder: "Username", onChange: (e: ChangeEvent<HTMLInputElement>) => console.log('changeEvent'), type: "text" }, passwordProps: { value: "", placeholder: "Password", onChange: (e: ChangeEvent<HTMLInputElement>) => console.log('changeEvent'), type: "password" }, isHidden: true, } // 用MemoryRouter包裹Login组件 render( <MemoryRouter> <Login {...loginProps} /> </MemoryRouter> ); screen.debug(); }) })
替代方案(Mock Link组件)
如果你只是想测试Login的其他部分,不想处理路由上下文,也可以mock Link组件:
vi.mock('react-router-dom', () => ({ ...vi.importActual('react-router-dom'), Link: ({ children }: { children: React.ReactNode }) => <span>{children}</span>, }));
这样Link会被替换成普通的span标签,避免依赖路由上下文。
内容的提问来源于stack exchange,提问作者jojeyh
相关产品推荐
相关产品推荐

