【问题标题】:Testing React Component with React Router V6使用 React Router V6 测试 React 组件
【发布时间】:2021-12-31 21:35:18
【问题描述】:

我知道 React 测试库有一个使用 react 路由器进行测试的示例,但我无法让它工作(我想是因为我使用的是 react 路由器 V6)。

基本上,我需要路由器测试,因为我有使用 useParams() 获取部分 url 的详细信息组件。没有它我无法渲染组件。

这是我试图让它工作的尝试(是的,页面也需要 apollo,尽管它并不真的需要 redux)。

const AllTheProviders = ({children, initialRoutes}) => {
    return (
        <ApolloProvider client={client}>
            <Provider store={store}>
                <MemoryRouter>
                    {children}
                </MemoryRouter>
            </Provider>
        </ApolloProvider>
    );
}
const customRender = (ui, options) => render(ui, {wrapper: AllTheProviders, ...options})


beforeEach(() => {
    window.history.pushState({}, 'Test page',"/details/url-param-the-component-needs")
    customRender(<App/>);
});

不足为奇,但这不起作用。我假设 window.history.pushState() 不适用于反应路由器 V6。我尝试使用 useNavigate(),但这在组件之外不起作用。

如果有人对我如何完成这项工作有任何想法。我将不胜感激。

【问题讨论】:

    标签: reactjs react-router react-router-dom react-testing-library


    【解决方案1】:

    MempryRouter 仍然采用 initialEntries 数组。

    MemoryRouter

    declare function MemoryRouter(
      props: MemoryRouterProps
    ): React.ReactElement;
    
    interface MemoryRouterProps {
      basename?: string;
      children?: React.ReactNode;
      initialEntries?: InitialEntry[];
      initialIndex?: number;
    }
    

    我会从customRender 中删除MemoryRouter,然后在本地包装被测组件并传入特定的初始路由条目以进行测试。

    const AllTheProviders = ({ children }) => {
      return (
        <ApolloProvider client={client}>
          <Provider store={store}>
            {children}
          </Provider>
        </ApolloProvider>
      );
    };
    const customRender = (ui, options) => 
      render(ui, { wrapper: AllTheProviders, ...options });
    

    ...

    const { ....queries.... } = customRender(
      <MemoryRouter
        initialEntries={["Test page", "/details/url-param-the-component-needs"]}
      >
        <ComponentUnderTest />
      </MemoryRouter>
    );
    

    另外考虑一下,useParams 钩子可能还需要一个 Route 和一个 path 属性来指定组件所需的匹配参数,因此您的测试可能如下所示:

    const { ....queries.... } = customRender(
      <MemoryRouter
        initialEntries={["Test page", "/details/url-param-the-component-needs"]}
      >
        <Routes>
          <Route path="/details/:theParam" element={<ComponentUnderTest />} />
        </Routes>
      </MemoryRouter>
    );
    

    【讨论】:

    • 这就像一个魅力。非常感谢!
    猜你喜欢
    • 2022-08-04
    • 2022-06-22
    • 2022-07-21
    • 2022-01-17
    • 2022-01-21
    • 1970-01-01
    • 2021-07-13
    • 2022-07-09
    • 2023-01-17
    相关资源
    最近更新 更多