You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试类组件中点击按钮时的Redux Dispatch逻辑?

React Testing Library 测试按钮点击触发Redux动作失败排查

我尝试用React Testing Library测试按钮点击时的组件功能,但多次尝试都没成功。

组件代码

import React, { Component } from "react";

import { connect } from "react-redux";
class Table extends Component {
  render() {
    const { removeRegister } = this.props;

    return (
      <button data-testid="delete-btn" onClick={() => removeRegister(0)}>
        Delete
      </button>
    );
  }
}
const mapStateToProps = () => ({});

const mapDispatchToProps = (dispatch) => ({
  removeExpense: (id) =>
    dispatch({
      type: "REMOVE_REGISTER",
      payload: { id },
    }),
});

export default connect(mapStateToProps, mapDispatchToProps)(Table);

测试代码

it("should trigger the actions when clicking on the buttons", () => {
  renderWithRouterAndRedux(<Table />, {
    state: mockState,
  });

  const deleteBtn = screen.getAllByTestId("delete-btn")[0];
  userEvent.click(deleteBtn);

  expect(store.dispatch).toHaveBeenCalledWith({ type: "REMOVE_REGISTER" });
});

问题排查与修复

1. Props名称不匹配

组件中调用的removeRegister并未在mapDispatchToProps中定义,实际导出的props是removeExpense,这会导致点击按钮时调用未定义方法,根本不会触发Redux dispatch。

修复方式二选一:

  • 组件内改用正确的props名称:
// 组件render方法内
const { removeExpense } = this.props;
// 按钮onClick改为
onClick={() => removeExpense(0)}
  • 或修改mapDispatchToProps的key为removeRegister:
const mapDispatchToProps = (dispatch) => ({
  removeRegister: (id) =>
    dispatch({
      type: "REMOVE_REGISTER",
      payload: { id },
    }),
});

2. 断言内容不完整

测试中只断言了action的type,但组件实际触发的action包含payload: {id:0},需要完整匹配action对象才能通过断言。

修正后的断言:

expect(store.dispatch).toHaveBeenCalledWith({
  type: "REMOVE_REGISTER",
  payload: { id: 0 }
});

3. 确保Store的Dispatch被正确监听

需要确保测试中能获取到Redux store,并且对dispatch方法进行spy监听。如果renderWithRouterAndRedux返回的对象包含store实例,直接使用即可;如果没有,需要手动添加spy:

修正后的测试代码:

it("should trigger the actions when clicking on the buttons", () => {
  // 获取render返回的store
  const { store } = renderWithRouterAndRedux(<Table />, {
    state: mockState,
  });
  // 对dispatch方法进行spy
  jest.spyOn(store, 'dispatch');

  // 单个按钮用getByTestId即可,无需getAll
  const deleteBtn = screen.getByTestId("delete-btn");
  userEvent.click(deleteBtn);

  expect(store.dispatch).toHaveBeenCalledWith({
    type: "REMOVE_REGISTER",
    payload: { id: 0 }
  });
});

内容的提问来源于stack exchange,提问作者LayTexas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 05:47:44