Сокращение хранилища определяет условную инициализацию с помощью localStorage во время тестирования — Библиотека тестирования React

#reactjs #redux #react-testing-library

Вопрос:

Я использую библиотеку тестирования React для тестирования некоторых функций моего веб-сайта, и я сталкиваюсь с проблемами с инициализацией хранилища Redux во время выполнения тестов. Ниже приведено начальное состояние:

 const initialState = {
      isAuth: false,
      loading: localStorage.getItem("authToken") ? true : false,
      error: false,
      user: {
           username: "",
      },
 };
 

Я настроил тесты с помощью следующего кода, чтобы обернуть все вокруг поставщика:

 import { FC, ReactElement } from "react";
import { render, RenderOptions } from "@testing-library/react";
import { Provider } from "react-redux";
import { store } from "../store/store";

const AllTheProviders: FC = ({ children }) => {
  return <Provider store={store}>{children}</Provider>;
};

const customRender = (
  ui: ReactElement,
  options?: Omit<RenderOptions, "wrapper">
) => render(ui, { wrapper: AllTheProviders, ...options });

export * from "@testing-library/react";
export { customRender as render };
 

Затем в фактическом тесте я использую beforeAll(() => window.localStorage.setItem("authToken", "mockToken") для установки токена в localStorage. В зависимости от значения loading состояния компонент входа в систему должен отображаться на моем веб-сайте, но я всегда получаю false в качестве значения загрузки.

 import { render, screen, waitFor } from "../utils/test-utils";
import App from "../App";

beforeAll(() => window.localStorage.setItem("authToken", "MockAuthToken"));

test("Login page not rendered if a valid auth token is present", async () => {
  render(<App />);
  
  //this is to check that the Login component is not rendered
  await waitFor(() => expect(screen.queryByText("Sign in")).toBeNull());

  await waitFor(() => expect(screen.getByRole("navigation")).toBeDefined(), {
    timeout: 5000,
  });
});
 

Это происходит потому, что хранилище Redux создается до выполнения функции setItem во время тестов? В то время как в браузере токен уже есть, когда я захожу на веб-сайт, и поэтому предполагаемое поведение не похоже на тест.

Ответ №1:

Это правильно. У нас есть открытая проблема с просьбой добавить перегрузку «функции отложенной инициализации» для initialState in createSlice :

https://github.com/reduxjs/redux-toolkit/issues/1024

Я действительно работал над попыткой реализовать это прошлой ночью и получил PR, но есть некоторые опасения по поводу изменений в семантике поведения:

https://github.com/reduxjs/redux-toolkit/pull/1662

Я еще посмотрю на это сегодня вечером и посмотрю, что мы можем придумать.