React 测试库不适用于 React Router v6
React testing library not work with react router v6
我几天前开始学习反应测试库,但我不知道如何让我的测试与反应路由器 v6 一起工作。我在下面有这两个测试:
describe('testing login page', () => {
test('veryfy inputs and buttons in login page', () => {
render(
<MemoryRouter initialEntries={['/']}>
<Routes>
<Route path="/" element={<LoginPage />} />
</Routes>
</MemoryRouter>,
);
const userInput = screen.getByRole('textbox');
expect(userInput).toBeInTheDocument();
describe('testing Mine Page', () => {
test('check table components', () => {
render(
<MemoryRouter initialEntries={['/mina']}>
<Routes>
<Route path="/mina" element={<MineTable />} />
</Routes>
</MemoryRouter>,
);
const pageTitle = screen.getByRole('heading', { name: /mina/i });
expect(pageTitle).toBeInTheDocument();
});
只有第一个测试有效,第二个不渲染页面MineTable,一直渲染最后一个页面登录。就像第一次测试渲染的历史一样。有人可以帮助我吗?我想测试我的应用程序的每个页面组件。
因为似乎 MineTable
使用了 useNavigate
钩子,所以它需要在它被渲染到的 ReactTree 中更高层提供路由上下文。
您只需要提供路由上下文,无需渲染路由等。为此,您可以直接使用 MemoryRouter
.
包装被测组件
describe('testing Mine Page', () => {
test('check table components', () => {
render(
<MemoryRouter>
<MineTable />
</MemoryRouter>,
);
const pageTitle = screen.getByRole('heading', { name: /mina/i });
expect(pageTitle).toBeInTheDocument();
});
});
事实上,这种需要提供上下文的模式非常普遍,以至于 RTL 有一个 wrapper
选项,您可以使用它来提供一个包装器组件,该组件提供组件使用的所有上下文,即路由、主题、 redux、语言环境翻译等...
示例:
const RouterWrapper = ({ children }) => (
<MemoryRouter>
{children}
</MemoryRouter>
);
...
import { RouterWrapper } from '../path/to/RouterWrapper";
describe('testing Mine Page', () => {
test('check table components', () => {
render(<MineTable />, { wrapper: RouterWrapper });
const pageTitle = screen.getByRole('heading', { name: /mina/i });
expect(pageTitle).toBeInTheDocument();
});
});
有关详细信息,请参阅 custom render。
我几天前开始学习反应测试库,但我不知道如何让我的测试与反应路由器 v6 一起工作。我在下面有这两个测试:
describe('testing login page', () => {
test('veryfy inputs and buttons in login page', () => {
render(
<MemoryRouter initialEntries={['/']}>
<Routes>
<Route path="/" element={<LoginPage />} />
</Routes>
</MemoryRouter>,
);
const userInput = screen.getByRole('textbox');
expect(userInput).toBeInTheDocument();
describe('testing Mine Page', () => {
test('check table components', () => {
render(
<MemoryRouter initialEntries={['/mina']}>
<Routes>
<Route path="/mina" element={<MineTable />} />
</Routes>
</MemoryRouter>,
);
const pageTitle = screen.getByRole('heading', { name: /mina/i });
expect(pageTitle).toBeInTheDocument();
});
只有第一个测试有效,第二个不渲染页面MineTable,一直渲染最后一个页面登录。就像第一次测试渲染的历史一样。有人可以帮助我吗?我想测试我的应用程序的每个页面组件。
因为似乎 MineTable
使用了 useNavigate
钩子,所以它需要在它被渲染到的 ReactTree 中更高层提供路由上下文。
您只需要提供路由上下文,无需渲染路由等。为此,您可以直接使用 MemoryRouter
.
describe('testing Mine Page', () => {
test('check table components', () => {
render(
<MemoryRouter>
<MineTable />
</MemoryRouter>,
);
const pageTitle = screen.getByRole('heading', { name: /mina/i });
expect(pageTitle).toBeInTheDocument();
});
});
事实上,这种需要提供上下文的模式非常普遍,以至于 RTL 有一个 wrapper
选项,您可以使用它来提供一个包装器组件,该组件提供组件使用的所有上下文,即路由、主题、 redux、语言环境翻译等...
示例:
const RouterWrapper = ({ children }) => (
<MemoryRouter>
{children}
</MemoryRouter>
);
...
import { RouterWrapper } from '../path/to/RouterWrapper";
describe('testing Mine Page', () => {
test('check table components', () => {
render(<MineTable />, { wrapper: RouterWrapper });
const pageTitle = screen.getByRole('heading', { name: /mina/i });
expect(pageTitle).toBeInTheDocument();
});
});
有关详细信息,请参阅 custom render。