使用@testing-library/react做路由单元测试报React不识别warnKey prop如何解决
报错诱因
你当前使用的是react-router v6版本,该版本对<Router>组件API做了破坏性变更:
- 原生
<Router>组件不再支持接收history属性作为入参,所有未被组件识别的props都会被直接透传给底层渲染的DOM元素 warnKey是React做非法DOM属性校验时附加的内部标记属性,随不合法的history参数一同透传给DOM后,触发了本次报错
测试用例能通过是因为路由逻辑本身没有执行错误,只是属性透传不符合React的规范,只抛出警告不阻塞主逻辑运行。
修复方案
有两种可选修复方式,优先选第一种即可:
方案1:使用官方推荐的测试专用路由组件
直接用react-router-dom内置的<MemoryRouter>替代自定义history+<Router>的写法,该组件默认基于内存历史实现,专门适配单元测试场景,不需要手动创建history实例。
修改后的测试代码如下:
import {render, screen} from '@testing-library/react' import React from 'react' import { MemoryRouter } from 'react-router-dom' import '@testing-library/jest-dom/extend-expect' import AdminPanel from './AdminPanel' test('full app rendering/navigating',async () => { render( // 如果AdminPanel对应特定路由,可以通过initialEntries指定初始路径 <MemoryRouter initialEntries={['/admin']}> <AdminPanel /> </MemoryRouter>, ) let title = await screen.findByText(/Admin Portal/i) expect(title).toBeInTheDocument() })
方案2:保留自定义history实例
如果你的测试逻辑需要对history做精细化控制,可以使用react-router-dom暴露的unstable_HistoryRouter替代原生<Router>,该组件支持传入自定义history属性:
修改后的代码如下:
import {render, screen} from '@testing-library/react' import {createMemoryHistory} from 'history' import React from 'react' import { unstable_HistoryRouter as HistoryRouter } from 'react-router-dom' import '@testing-library/jest-dom/extend-expect' import AdminPanel from './AdminPanel' test('full app rendering/navigating',async () => { const history = createMemoryHistory() render( <HistoryRouter history={history}> <AdminPanel /> </HistoryRouter>, ) let title = await screen.findByText(/Admin Portal/i) expect(title).toBeInTheDocument() })
内容的提问来源于stack exchange,提问作者Yusuf Khan
相关产品推荐
相关产品推荐

