Настройка маршрутов для браузера в тестах

#reactjs #react-router #react-router-v6

Вопрос:

У меня есть тестовый случай, в котором мне нужно начать со страницы регистрации ( /signup ), и при успешной регистрации приложение должно перейти на домашнюю страницу ( / ). В настоящее время я использую MemoryRouter для установки начального маршрута /signup , и все работает хорошо. Смотреть ниже:

 import React from 'react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router';
import { Route, Routes } from 'react-router-dom';
import { render, screen } from '../../test/test-utils';
import { SignUpPage } from './SignUpPage';

const MockHomePage = () => <div>MockHomePage</div>;

describe('<SignUp />', () => {
  test('navigates to Home page on successful signup', async () => {
    render(
      <MemoryRouter initialEntries={['/signup']}>
        <Routes>
          <Route path="/" element={<MockHomePage />} />
          <Route path="/signup" element={<SignUpPage />} />
        </Routes>
      </MemoryRouter>
    );

    // Enter valid user info and submit form
    userEvent.type(screen.getByLabelText('Full Name'), 'John Smith');
    userEvent.type(screen.getByLabelText('Email'), 'johnsmith@gmail.com');
    userEvent.type(screen.getByLabelText('Password'), 'let-me-in');
    userEvent.type(screen.getByLabelText('Confirm Password'), 'let-me-in');
    userEvent.click(screen.getByText('Sign up'));

    // Expect to see the Home page
    expect(await screen.findByText('MockHomePage')).toBeInTheDocument();
  });
});
 

Тем не менее, я хотел бы использовать BrowserRouter в своих тестах вместо MemoryRouter (я понимаю, что это рекомендуемый способ, так как он ближе к тому, что будет использовать реальное приложение). К сожалению, BrowserRouter у него нет initialEntries опоры (я использую маршрутизатор React v6 beta.7). Есть ли способ заставить BrowserRouter начать с /signup этого ?

Я попробовал API определения местоположения следующим образом:

 window.location.href = 'http://localhost:3000/signup';
 

Однако я получаю ошибку jsdom, в которой говорится, что этот API не реализован:

 Error: Not implemented: navigation (except hash changes)
  at module.exports (/Users/naresh/projects/accelerated-news/node_modules/jsdom/lib/jsdom/browser/not-implemented.js:9:17)
 

Есть ли какой-нибудь другой способ?

Ответ №1:

Я считаю, что вам нужно использовать window.history.pushState() , чтобы это выглядело примерно так:

 test('navigates to Home page on successful signup', async () => {
  window.history.pushState({}, '', '/signup')

  render(
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<MockHomePage />} />
        <Route path="/signup" element={<SignUpPage />} />
      </Routes>
    </BrowserRouter>
  );

  // etc..
});