Как проверить компонент ProtectedRoute. (Инвариант не удался: вы не должны использовать <Route>вне <Router>) - PullRequest
0 голосов
/ 18 января 2020

Я создал этот компонент для создания компонента ProtectedRoute, который можно использовать для проверки того, прошел ли пользователь проверку подлинности и будет ли он перенаправлен на маршруты или будет предложено войти в систему.

/* eslint-disable
react/jsx-props-no-spreading,
no-undef, import/no-extraneous-dependencies,
no-unused-expressions,
no-return-assign,
prettier/prettier
*/
import { Redirect, Route } from 'react-router';
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { isValidElementType } from 'react-is';
import toast from '../lib/toast';
import setAuthenticate from '../store/actions/authenticateAction';

export const ProtectedRoute = ({
    setAuthState,
    component: Component,
    ...rest
}) => {
    setAuthState(true);
    const isAuthenticated = !!localStorage.bn_user_data;
    !isAuthenticated && toast('error', 'You need to be logged in');

    return (
        <Route
            data-test='protected-route'
            render={props =>
                isAuthenticated ? (
                    <Component {...props} />
                ) : (
                    <Redirect
                        to={{ pathname: '/login', state: { from: props.location } }}
                    />
                    // eslint-disable-next-line prettier/prettier
                )}
            {...rest}
        />
    );
};

ProtectedRoute.propTypes = {
    component: (props, propName) => {
        if (props[propName] && !isValidElementType(props[propName])) {
            return new Error(
                `Invalid prop 'component' supplied to 'Route':
                 the prop is not a valid React component`,
            );
        }
    },
    location: PropTypes.shape({
        pathname: PropTypes.string.isRequired,
    }),
    setAuthState: PropTypes.func.isRequired,
};

ProtectedRoute.defaultProps = {
    location: null,
    component: null,
};

export default connect(null, {
    setAuthState: setAuthenticate,
})(ProtectedRoute);

И вот мой тест для рендеринга этого компонента:

import React from "react";
import { ProtectedRoute } from "../../components/ProtectedRoute";
import { render } from "@testing-library/react";

describe("\"ProtectedRoute\"", () => {
  beforeAll(() => {
    const user_data = `{
      "email":"requestero@user.com",
      "name":"Requester",
      "userId":2,
      "verified":true,
      "role":"requester",
      "lineManagerId":7,
      "iat":1578472431,
      "exp":1578558831
    }`;
    global.localStorage = {
      bn_user_data: user_data,
    };
  });
  it("should render without error", function() {
    const { getByTestId } = render(
        <ProtectedRoute setAuthState={jest.fn()}/>
      );
  });
});

Компонент работает хорошо, но я не могу построить тест для него, он ошибается с этой ошибкой:

Invariant failed: You should not use <Route> outside a <Router>

Поэтому мне нужен совет о том, как реализовать тест с помощью jest, как это реализовать.

1 Ответ

0 голосов
/ 18 января 2020

Я нашел способ обойти эту проблему, используя фермент вместо библиотеки реагирующих тестов:

import React from "react";
import { ProtectedRoute } from "../../components/ProtectedRoute";
import { shallow } from "enzyme";

const setUp = (props = {}) => shallow(<ProtectedRoute {...props} />);
describe("\"ProtectedRoute\"", () => {
  let wrapper;
  const props = {
    setAuthState: jest.fn()
  };
  beforeAll(() => {
    const user_data = `{
      "email":"requestero@user.com",
      "name":"Requester",
      "userId":2,
      "verified":true,
      "role":"requester",
      "lineManagerId":7,
      "iat":1578472431,
      "exp":1578558831
    }`;
    global.localStorage = {
      bn_user_data: user_data
    };
    wrapper = setUp(props);
  });
  it("should render without error", function() {
    const component = wrapper.find(`[data-test='protected-route']`);
    expect(component.length).toBe(1);
  });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...