无法在 Jest 中调度操作

问题描述 投票:0回答:1

我们在 React 应用程序中有一个购物车组件:

import { useDispatch, useSelector } from "react-redux";
import ItemList from "./ItemList";
import { clearCart } from "../slice/cartSlice";

const Cart = () => {

  const dispatch = useDispatch();
  const cartItems = useSelector((store) => store.cart.items);

  const handleClearCart = () => {
    console.log("Here in the handle clear cart onClick event handler");
    console.log("clearCart function is ", clearCart);
    dispatch(clearCart());
  };

  return (
    <div>
      <h1> Cart </h1>
      {cartItems.length != 0 && (
        <button
          onClick={handleClearCart}
        >
          Clear Cart
        </button>
      )}
      {cartItems.length ? (
        <div>
          <ItemList items={cartItems} />
        </div>
      ) : (
        <h3> Your cart is empty !</h3>
      )}
    </div>
  );
};

export default Cart;

这是我们正在使用的 cartSlice :

import { createSlice, current } from "@reduxjs/toolkit";

const cartSlice = createSlice({
  name: "cart",
  initialState: { items: [] },
  reducers: {
    addItem: (state, action) => {
      state.items.push(action.payload);
    },
    removeItem: (state, action) => {
      const filteredList = state.items.filter(
        (item, index) => index != action.payload
      );
      return {
        ...state,
        items: filteredList,
      };
    },
    clearCart: (state) => {
      console.log("Here in the clear cart reducer");
      state.items.length = 0;
    },
  },
});

export const { addItem, removeItem, clearCart } = cartSlice.actions;
export default cartSlice.reducer;

在 UI 上,当我们单击清除购物车按钮时,它会清除购物车并显示消息“您的购物车为空”。

我们正在尝试在 Jest/React 测试库中编写相同的单元测试。这是我们的尝试:

import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";
import { Provider } from "react-redux";
import configureMockStore from "redux-mock-store";
import mockStoreInfo from "../__mocks__/storeMock";
import Cart from "../src/components/Cart";

    test("should clear cart when click on clear cart in cart component", async () => {
    render(
      <Provider store={storeMock}>
        <Cart />
      </Provider>
    );
    const clearCartButton = screen.getByRole("button", { name: "Clear Cart" });
    expect(clearCartButton).toBeInTheDocument();
    console.log("clearCart button is", clearCartButton);
    fireEvent.click(clearCartButton);
    expect(await (screen.getByText(" Your cart is empty !"))).toBeInTheDocument();
  });

从我们可以看到,

clear Cart
按钮已被记录并且是一个有效的按钮。
handleClearCart
函数也被调用,我们也可以打印
clearCart
函数体。但是,我们无法从 CartSlice 中的
clearCart
操作中看到控制台日志,这表明它没有被调用,因此断言
 Your cart is empty !
的测试失败。我们不确定为什么单击该按钮时没有调度该操作。有人可以帮助我们吗?

PS:我们从失败的测试中得到的 DOM 结构表明购物车尚未被清除。这是 DOM:

<body>
  <div>
    <div class="cart-container" data-testid="cart">
      <h1 class="cart-heading">Cart</h1>
      <button class="clear-cart" data-testid="clear-cart">Clear Cart</button>
      <div class="cart-items" data-testid="cart-items-list">
        <div>
          <div class="menu-item">
            <div class="sc-guDLey byrpfT">
              <div class="menu-header">
                <span> Al Fungi Gourmet-Pizza </span>
                <span> - ₹ 549 </span>
              </div>
              <p class="accordion-body-description">
                Gourmet mushroom pizza on a cheesy Mozzarella base with
                jalapenos & cherry tomatoes.
              </p>
            </div>
            <div class="sc-beySPh fSyZNZ">
              <img
                class="accordion-image"
                src="https://res.cloudinary.com/swiggy/image/upload/fl_lossy,f_auto,q_auto,w_508,h_320,c_fill/4ffebb537f043e94e09e928f48e640e9"
              />
              <button class="accordion-button-delete">Remove -</button>
            </div>
          </div>
          <div class="menu-item">
            <div class="sc-guDLey byrpfT">
              <div class="menu-header">
                <span> Butterscotch Mousse Cake </span>
                <span> - ₹ 103.81 </span>
              </div>
              <p class="accordion-body-description">
                Sweet temptation! Butterscotch flavored mousse
              </p>
            </div>
            <div class="sc-beySPh fSyZNZ">
              <img
                class="accordion-image"
                src="https://res.cloudinary.com/swiggy/image/upload/fl_lossy,f_auto,q_auto,w_508,h_320,c_fill/e91002ccf7239fffeceaab4956a15a3a"
              />
              <button class="accordion-button-delete">Remove -</button>
            </div>
          </div>
          <div class="menu-item">
            <div class="sc-guDLey byrpfT">
              <div class="menu-header">
                <span> Choco Lava Cake </span>
                <span> - ₹ 109 </span>
              </div>
              <p class="accordion-body-description">
                Chocolate lovers delight! Indulgent, gooey molten lava inside
                chocolate cake
              </p>
            </div>
            <div class="sc-beySPh fSyZNZ">
              <img
                class="accordion-image"
                src="https://res.cloudinary.com/swiggy/image/upload/fl_lossy,f_auto,q_auto,w_508,h_320,c_fill/517791a68253a9a5084664b470f6e115"
              />
              <button class="accordion-button-delete">Remove -</button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
reactjs unit-testing react-redux jestjs react-testing-library
1个回答
0
投票

redux-mock-store
已经过时了。在单元测试中创建真正的 Redux 存储是常见的建议和实践。 Redux-Toolkit 创建的商店已集成并默认启用 Thunk 中间件。

示例:

import React from 'react';
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";
import { configureStore } from "@reduxjs/toolkit"; // <-- create real store
import { Provider } from 'react-redux';
import reducer from '../path/to/rootReducer'; // <-- import reducer
import Cart from "../src/components/Cart";

const preloadedState = {
  // any initial state necessary for the unit tests
};

const store = configureStore({
  preloadedState,
  reducer,
});

const Providers = ({ children }) => (
  <Provider store={store}>
    {children}
  </Provider>
);

test("should clear cart when click on clear cart in cart component", async () => {
  render(<Cart />, { wrapper: Providers });

  const clearCartButton = screen.getByRole("button", { name: "Clear Cart" });
  expect(clearCartButton).toBeInTheDocument();

  console.log("clearCart button is", clearCartButton);

  fireEvent.click(clearCartButton);

  expect(await (screen.getByText(" Your cart is empty !"))).toBeInTheDocument();
});

请参阅 Redux Writing Tests 文档,了解更多一般测试信息和策略。

© www.soinside.com 2019 - 2024. All rights reserved.