Тестирование реакции-роутера перенаправляет с Jest и Enzyme - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть простой компонент React, использующий реагирующий маршрутизатор, который перенаправляет пользователя, если у него нет разрешения на просмотр определенного маршрута:

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {permission: false};
  }

  render() {
    return (
      <Switch>
        <Route exact path="/users">
          <h2>A list of users</h2>
        </Route>
        <Route path="/users/:userId">
          {({match}) => this.state.permission ? <h1>{match.params.userId}</h1> : <Redirect to="/users" />}
        </Route>
      </Switch>
    );
  }
}

Я пытаюсь протестировать различные сценарии при доступе /users/:userId с использованием Jest и Enzyme, но не удается выполнить тест, если у пользователя есть разрешение.

Мои тесты следующие:

describe("render()", () => {
  describe("when route is /users/:userId", () => {
    let wrapper;
    let app;
    beforeEach(() => {
      wrapper = mount(
        <MemoryRouter initialEntries={["/users/1"]}>
          <App />
        </MemoryRouter>
      );
      app = wrapper.find(App).instance();
    });

    describe("when user has permission", () => {
      beforeEach(() => {
        app.setState({permission: true});
      });

      it("should show users id", () => {
        expect(wrapper.exists("h1")).toBe(true);
      });
    });

    describe("when user doesn't have permission", () => {
      beforeEach(() => {
        app.setState({permission: false});
      });

      it("should redirect to users list", () => {
        expect(wrapper.exists("h2")).toBe(true);
      });
    });
  });
});

Первый тест не пройден, а второйпреуспевает.Я использовал console.log(wrapper.debug()); в первом тесте, и он показывает, что компонент рендерит первый маршрут (т.е. перенаправляется), и я распечатал состояние, чтобы я мог видеть, что вызов setState работает.

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

1 Ответ

0 голосов
/ 17 сентября 2018

Issue

Исходное местоположение установлено на /users/1, но когда компонент монтируется в первый раз, он отображает Redirect, который устанавливает местоположение на /users.

permissionзатем установите на true, но, поскольку местоположение - /users, результат - <h2>A list of users</h2>.


Решение

После установки permission на true установите местоположение на/users/1, поэтому местоположение правильное и тест успешно отображает <h1>1</h1>:

describe("render()", () => {
  describe("when route is /users/:userId", () => {
    let wrapper;
    let app;
    beforeEach(() => {
      wrapper = mount(
        <MemoryRouter initialEntries={["/users/1"]}>
          <App />
        </MemoryRouter>
      ); // the Redirect sets location to /users during the initial render
      app = wrapper.find(App).instance();
    });

    describe("when user has permission", () => {
      beforeEach(() => {
        app.setState({permission: true});
        wrapper.instance().history.replace('/users/1'); // replace the MemoryRouter location with /users/1
        wrapper.update(); // update the wrapper with the changes
      });

      it("should show users id", () => {
        expect(wrapper.exists("h1")).toBe(true); // SUCCESS
      });
    });

    describe("when user doesn't have permission", () => {
      beforeEach(() => {
        app.setState({permission: false});
      });

      it("should redirect to users list", () => {
        expect(wrapper.exists("h2")).toBe(true);
      });
    });
  });
});
...