使用Enzyme单元测试React-Redux连接组件遇报错求助
解决React-Redux组件mount测试时'Actions must be plain objects'报错问题
没问题,这个报错我之前也踩过坑——本质是你的组件提交时发起的Redux action(尤其是异步action,比如用thunk的那种)不是纯对象,而你配置的mock store没加对应的中间件处理,或者没正确模拟dispatch调用。下面给你两种靠谱的解决思路,附代码示例:
方法一:用redux-mock-store配置中间件(推荐,可同时验证action)
如果你想既避免报错,又能验证组件是否正确触发了预期的action,就用这种方式:
首先确保你已经安装了依赖:
npm install redux-mock-store --save-dev
然后按照下面的结构写测试代码:
import React from "react"; import { mount } from "enzyme"; import { Provider } from "react-redux"; import configureStore from "redux-mock-store"; import thunk from "redux-thunk"; // 项目里用了thunk中间件的话必须加这个 import YourFormComponent from "../components/YourFormComponent"; import { submitFormAction } from "../actions/formActions"; // 导入你要验证的action // 配置mock store,把项目用到的中间件加进去(比如thunk) const mockStore = configureStore([thunk]); describe("YourFormComponent", () => { let store; let wrapper; beforeEach(() => { // 初始化mock store的初始状态,和组件需要的state对应 const initialState = { form: { username: "", password: "" }, loading: false }; store = mockStore(initialState); // 用Provider包裹组件,传入mock store wrapper = mount( <Provider store={store}> <YourFormComponent /> </Provider> ); }); it("dispatches the correct action when form is submitted", () => { // 模拟用户输入表单内容(按需添加) wrapper.find('input[name="username"]').simulate("change", { target: { value: "test_user" } }); // 触发表单提交 wrapper.find('button[type="submit"]').simulate("click"); // 获取mock store记录的所有dispatch动作 const dispatchedActions = store.getActions(); // 验证是否触发了预期的action expect(dispatchedActions).toContainEqual(submitFormAction("test_user")); // 也可以直接验证action的类型和payload expect(dispatchedActions[0].type).toBe("FORM_SUBMIT_REQUEST"); expect(dispatchedActions[0].payload.username).toBe("test_user"); }); });
关键说明:
- 如果你用了redux-thunk、redux-saga这类处理异步action的中间件,必须把它们加入
configureStore的参数数组里,否则mock store无法识别非纯对象的action,就会抛出你遇到的错误。 mockStore会自动记录所有dispatch的动作,你可以用store.getActions()来获取并做断言,这对测试组件的行为逻辑很有用。
方法二:直接mock dispatch方法(快速避免报错)
如果你只是想跳过action的执行,单纯测试组件的UI交互,可以直接mock store的dispatch方法:
// 在创建store之后,覆盖dispatch为jest mock函数 store.dispatch = jest.fn(); // 之后不管组件里怎么调用dispatch,都不会执行真实逻辑,也不会报错
这种方式适合只关注组件UI交互,暂时不需要验证action的场景。
内容的提问来源于stack exchange,提问作者Nayeem
相关产品推荐
相关产品推荐

