首页 > 解决方案 > Redux 存储在测试期间使用 localStorage 进行条件初始化 - React 测试库

问题描述

我正在使用 React 测试库来测试我网站的一些功能,并且在运行测试时遇到了 Redux 存储初始化的问题。以下是初始状态:

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

我已经使用以下代码设置了测试,以将所有内容包装在 Provider 周围:

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中设置token。根据loading状态的值,登录组件应该在我的网站上呈现,但我总是得到错误的加载值。

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函数执行之前创建的吗?在浏览器中,当我进入网站时令牌已经存在,因此预期的行为与测试不相似。

标签: reactjsreduxreact-testing-library

解决方案


这是正确的。我们有一个未解决的问题,要求我们为initialStatein添加“延迟初始化函数”重载createSlice

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

实际上,我昨晚正在努力尝试实现这一点并进行 PR,但是对于行为语义的变化存在一些担忧:

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

今晚我会再看看这个,看看我们能想出什么。


推荐阅读