【问题标题】:React-Testing-Library Setup for Redux, Router and Dynamic Modules using TypeScript使用 TypeScript 为 Redux、路由器和动态模块设置 React-Testing-Library
【发布时间】:2020-08-10 13:55:26
【问题描述】:

我有一个小应用程序,它使用redux-dynamic-modules 作为存储,react-router 用于路由,所有组件都是带有钩子的函数组件,例如useState,useHistory,useLocation,useSelector,@987654328 @等

我想设置react-testing-library 来测试组件,正如in documentation 所说,我需要设置一个自定义render()。

这是我的index.tsx

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { Provider } from "react-redux";
import { store } from "./redux/store";


ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

这是我的 App.tsx

import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import { SearchPage } from "./pages/search/search-page";
import { LayoutComponent as Layout } from "./components/shared/layout/layout";
import { DynamicModuleLoader } from "redux-dynamic-modules";
import { reduxSearch } from "./redux/search";
import { store } from "./redux/store";
import { paths } from "./lib/constants/paths";


const App = () => {
  return (
    <>
      <Router>
        <DynamicModuleLoader
          modules={[reduxSearch()]}
          createStore={() => store}
        >
        <Layout>
          <Route exact path={paths.search}>
            <SearchPage />
          </Route>
        </Layout>
        </DynamicModuleLoader>
      </Router>
    </>
  );
};

export default App;

最后是我为自定义渲染器创建的test-utils.tsx:

import React, { ReactElement, ReactNode } from "react";
import { render as rtlRender, RenderOptions } from "@testing-library/react";
import { DynamicModuleLoader } from "redux-dynamic-modules";
import { Provider } from "react-redux";
import { reduxSearch } from "../redux/search";
import { store, history } from "../redux/store";
import { Router } from "react-router-dom";

export interface WrapperProps {
  children: ReactElement;
}

const render = (ui: ReactElement, renderOptions?: RenderOptions) => {
  const Wrapper = ({ children }: WrapperProps): ReactElement => {
    return (
      <Provider store={store}>
        <Router history={history}>
          <DynamicModuleLoader
            modules={[reduxSearch()]}
            createStore={() => store}
          >
            {children}
          </DynamicModuleLoader>
        </Router>
      </Provider>
    );
  };
  return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
};

// re-export everything
export * from "@testing-library/react";

// override render method
export { render };
):

我似乎遵循提供的文档和示例,但我在 TSLint 控制台的这一行 return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });(wrapper 带有下划线)中收到此错误

  Overload 1 of 2, '(ui: ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)>, options?: Pick<...> | undefined): RenderResult<...>', gave the following error.
    Type '({ children }: WrapperProps) => React.ReactElement<any, string | ((props: any) => React.ReactElement<any, string | ... | (new (props: any) => React.Component<any, any, any>)> | null) | (new (props: any) => React.Component<...>)>' is not assignable to type 'ComponentClass<{}, any> | FunctionComponent<{}> | undefined'.
      Type '({ children }: WrapperProps) => React.ReactElement<any, string | ((props: any) => React.ReactElement<any, string | ... | (new (props: any) => React.Component<any, any, any>)> | null) | (new (props: any) => React.Component<...>)>' is not assignable to type 'FunctionComponent<{}>'.
        Types of parameters '__0' and 'props' are incompatible.
          Type '{ children?: ReactNode; }' is not assignable to type 'WrapperProps'.
            Types of property 'children' are incompatible.
              Type 'ReactNode' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)>'.
                Type 'undefined' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)>'.
  Overload 2 of 2, '(ui: ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)>, options: RenderOptions<...>): RenderResult<...>', gave the following error.
    Type '({ children }: WrapperProps) => React.ReactElement<any, string | ((props: any) => React.ReactElement<any, string | ... | (new (props: any) => React.Component<any, any, any>)> | null) | (new (props: any) => React.Component<...>)>' is not assignable to type 'ComponentClass<{}, any> | FunctionComponent<{}> | undefined'.
      Type '({ children }: WrapperProps) => React.ReactElement<any, string | ((props: any) => React.ReactElement<any, string | ... | (new (props: any) => React.Component<any, any, any>)> | null) | (new (props: any) => React.Component<...>)>' is not assignable to type 'FunctionComponent<{}>'.```

什么是正确的设置方法,测试连接的组件?

【问题讨论】:

    标签: reactjs typescript redux react-testing-library redux-dynamic-modules


    【解决方案1】:

    您收到该错误是因为您的道具与包装器属性的预期不兼容。您可以通过添加 React 的功能组件类型来轻松修复它,其中包含 children 的定义:

    import React, { ReactElement, ReactNode } from "react";
    import { render as rtlRender, RenderOptions } from "@testing-library/react";
    import { DynamicModuleLoader } from "redux-dynamic-modules";
    import { Provider } from "react-redux";
    import { reduxSearch } from "../redux/search";
    import { store, history } from "../redux/store";
    import { Router } from "react-router-dom";
    
    
    const render = (ui: ReactElement, renderOptions?: RenderOptions) => {
      const Wrapper : React.FC = ({ children }) => {
        return (
          <Provider store={store}>
            <Router history={history}>
              <DynamicModuleLoader
                modules={[reduxSearch()]}
                createStore={() => store}
              >
                {children}
              </DynamicModuleLoader>
            </Router>
          </Provider>
        );
      };
      return rtlRender(ui, { wrapper: Wrapper, ...renderOptions });
    };
    
    // re-export everything
    export * from "@testing-library/react";
    
    // override render method
    export { render };
    
    

    【讨论】:

    • 谢谢!现在我在测试中遇到了一个不同的错误:TypeError: window.matchMedia is not a function - on rtlRender() - 但情况不同
    • 创建一个问题并链接我,我也有一个解决方案:)
    • 谢谢,这将与this 重复
    猜你喜欢
    • 2019-09-12
    • 2021-07-05
    • 2021-07-18
    • 2019-06-14
    • 2022-08-06
    • 1970-01-01
    • 2019-10-30
    • 2019-07-07
    • 1970-01-01
    相关资源
    最近更新 更多