Настройка React-Testing-Library для модулей Redux, Router и Dynami c с использованием TypeScript - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть небольшое приложение, которое использует redux-dynamic-modules в качестве хранилища, react-router для маршрутизации, и все компоненты являются функциональными компонентами с хуками, такими как useState, useHistory, useLocation, useSelector, useDispatch et c.

Я хочу настроить react-testing-library для проверки компонентов и, как сказано в документации Мне нужно настроить пользовательский 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, который я создал для рендерера cusom:

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<{}>'.```

Как правильно настроить это, чтобы проверить подключенные компоненты?

1 Ответ

1 голос
/ 27 апреля 2020

Вы получаете эту ошибку, потому что ваши реквизиты не совместимы с ожидаемыми для свойства оболочки. Вы можете легко исправить это, добавив тип функционального компонента 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 };

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...