Dos*_*kya 6 javascript testing reactjs react-router react-testing-library
将 React Router DOM (v6) 与 React 测试库结合使用,我想知道是否有一种方法可以处理“模拟”历史记录createMemoryHistory或类似的替代方案。
根据测试库的示例,我可以模拟组件的历史记录Router,但在 v6 中该组件不再接受该historyprop。
所以,我的疑问是:如何使用 React Router DOM v6 使用 RTL(React 测试库)测试历史记录和位置?我应该继续使用MemoryRouter吗?
小智 14
使用 React Router DOM v6.4.0 的推荐测试方法依赖于createMemoryRouter哪个将返回RemixRouter. 可以使用Router 的对象来history代替使用,因为该 Router使用其自己的内存历史记录。该对象包含我们可以检查导航是否正确的位置。createMemoryHistorystatecreateMemoryRouterstate
使用RouterProviderReact Router DOM,我们可以将创建的路由器传递createMemoryRouter给提供者并传递给我们的测试。
import { render, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {
createMemoryRouter,
RouterProvider,
useNavigate,
} from 'react-router-dom'
import { screen } from '@testing-library/react'
// The element we want to render. Uses the hook useNavigate to send us somewhere.
const ElementToRender: React.FC = () => {
const navigate = useNavigate()
return <button onClick={() => navigate('/')}>Navigate to Home</button>
}
const setupMyTest = () => {
const router = createMemoryRouter(
[
{
path: '/',
element: <>Navigated from Start</>,
},
{
path: '/starting/path',
// Render the component causing the navigate to '/'
element: <ElementToRender />,
},
],
{
// Set for where you want to start in the routes. Remember, KISS (Keep it simple, stupid) the routes.
initialEntries: ['/starting/path'],
// We don't need to explicitly set this, but it's nice to have.
initialIndex: 0,
}
)
render(<RouterProvider router={router} />)
// Objectify the router so we can explicitly pull when calling setupMyTest
return { router }
}
it('tests react router dom v6.4.0 navigates properly', async () => {
const { router } = setupMyTest()
// Given we do start where we want to start
expect(router.state.location.pathname).toEqual('/starting/path')
// Navigate away from /starting/path
userEvent.click(screen.getByRole('button', { name: 'Navigate to Home' }))
// Don't forget to await the update since not all actions are immediate
await waitFor(() => {
expect(router.state.location.pathname).toEqual('/')
})
})
Run Code Online (Sandbox Code Playgroud)
Jur*_*r P -4
使用react router dom v6,路由器使用 navigator prop 来接受历史记录。
const history = createMemoryHistory();
...
<MockedProvider mocks={[]}>
<Router navigator={history} location={"/"}>
<Home />
</Router>
</MockedProvider>
...
await waitFor(() => {
expect(history.location.pathname).toBe("/");
});
Run Code Online (Sandbox Code Playgroud)