尝试在 jest/RTL 中编写单元测试时,如何将一些状态添加到 redux 状态?

How do I add some state to redux state when try to write unit test in jest/RTL?

根据我找到的文章,我想开始使用 Redux-toolkit 进行测试。

https://redux.js.org/usage/writing-tests#setting-up

正确的做法是编写集成测试。但现在我想测试一个由 authstate 控制的注销按钮,为了设置它的值,我必须先登录。我想做的是我可以在测试文件中为 authstate 提供一些状态,而不必登录。所以我实际上可以在退出按钮上编写单元测试。

这是代码和测试

const Navbar = () => {
  const cart = useAppSelector((state) => state.cart);
  const user = useAppSelector((state) => state.auth);
  const dispatch = useAppDispatch();
  const handleLogout = () => {
    localStorage.removeItem("persist:root");
    window.location.reload();
  };
  return(
     {user.user !== null ? (
            <>
              <MenuItem>Hello {user.user?.username} </MenuItem>{" "}
              <ExitToApp
                style={{ cursor: "pointer", marginLeft: "10px" }}
                onClick={() => handleLogout()}
              />
              <Link to="/order">
                <MenuItem>Order</MenuItem>
              </Link>
            </>
          ) : (
            <>
              <Link to="/register">
                <MenuItem>REGISTER</MenuItem>
              </Link>
              <Link to="/login">
                <MenuItem>SIGN IN</MenuItem>
              </Link>
            </>
          )}
  )

Authslice

const slice = createSlice({
  name: "auth",
  initialState: { user: null, token: null } as {
    user: null | UserDataInterface;
    token: null | string;
  },
  reducers: {
    setCredentials: (state,{ payload: { user, token } }: PayloadAction<{ user: UserDataInterface; token: string }>) => {
      state.user = user;
      state.token = token;
    }
  },
  extraReducers: (builder) => {}
});

测试文件

test("When click on logoutk,it will trigger handle logout", () => {
   //TODO: should let the user state to not be empty first 
   await store.dispatch(setCredentials())
   //TODO: then we can track if logout label exist
   //TODO: click on logout button and mock localstorage maybe ?
});

这种单元测试,涉及到redux-state的先决条件怎么办?

经过一些研究,我发现了如何做到这一点。这可能不是最佳做法。但我认为如果你不想编写集成测试,它在很多情况下可能会有用。

test("When click on logout,it will trigger handle logout", async () => {
    //TODO: should let the user state to not be empty first
    store.dispatch(
      setCredentials({
        user: {
          username: "Kai",
          _id: "efekfjefke",
          email: "dfdkdfkdf@gmail.com",
          createdAt: new Date(2013, 13, 1),
          updatedAt: new Date(2013, 13, 1),
          img: "223232",
        },
        token: "test12345",
      })
    );
    //TODO: then we can track if logout label exist
    await waitFor(() =>
      expect(screen.queryByRole("userTitle")).toBeInTheDocument()
    );
    await waitFor(() =>
      expect(screen.queryByTestId("logout")).toBeInTheDocument()
    );
    //TODO: click on logout button and mock localstorage maybe ?
    const userLogout = screen.getByTestId("logout");
    fireEvent.click(userLogout);
    // should not be able to query the userTitle since it's logout
    await waitFor(() =>
      expect(screen.queryByRole("userTitle")).not.toBeInTheDocument()
    );
  });

我发现您可以通过商店直接调度状态。真的很方便

因为我。棘手的是我不知道如何编写跨两个组件或页面的集成测试

现在,如果我可以先直接发送一些状态。我可以 unit-test 单个页面或组件中的功能,看看它是否满足我的需要。

我是测试新手,所以如果有更好的方法,请告诉我!

希望这可以帮助正在挣扎的人!!