使用Jest和Enzyme测试Redux异步Action时,userDispatch返回匿名函数与预期Action对象不符的问题求助
解决Redux Action测试中返回匿名函数而非Action对象的问题
你遇到的问题其实很好理解——userDispatch是一个Redux Thunk函数,它本身并不直接返回Action对象,而是返回一个接收dispatch参数的匿名函数。你的测试用例直接调用actions.userDispatch(data),拿到的自然就是这个匿名函数,而非你期望的{ type: USER, data }。
咱们先拆解下代码逻辑:
user是普通的Action creator,调用它会直接返回标准的Action对象;userDispatch是Thunk函数,它的作用是封装逻辑(哪怕是同步逻辑),返回的函数会在Redux环境中被调用,接收dispatch后再去分发真正的Action(也就是user(data))。
解决方案:测试Thunk函数的正确姿势
要测试Thunk函数,我们需要模拟Redux的dispatch环境,让Thunk内部的逻辑执行起来,然后验证它是否分发了正确的Action。这里有两种常用方式:
方式1:手动模拟dispatch(适合同步逻辑)
如果你的Thunk里没有异步操作(比如没有API请求),可以直接手动传入模拟的dispatch函数:
it("testing userDispatch dispatches the correct action", () => { const data = true; const expectedAction = { type: USER, data }; // 创建一个模拟的dispatch函数,用jest.mock追踪调用 const mockDispatch = jest.fn(); // 调用Thunk函数,并传入模拟的dispatch actions.userDispatch(data)(mockDispatch); // 验证dispatch是否被调用,且传入的参数是预期的Action expect(mockDispatch).toHaveBeenCalledWith(expectedAction); });
方式2:使用redux-mock-store(贴近真实Redux环境)
如果你的Thunk里有异步逻辑,或者想更完整地模拟Redux store,可以用redux-mock-store结合thunk中间件:
首先安装依赖:
npm install redux-mock-store --save-dev
然后编写测试用例:
import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import * as actions from './your-action-file'; // 替换成你的Action文件路径 import { USER } from './your-constants-file'; // 替换成你的常量文件路径 // 创建带thunk中间件的模拟store const middlewares = [thunk]; const mockStore = configureMockStore(middlewares); it("testing userDispatch dispatches the correct action", () => { const data = true; const expectedAction = { type: USER, data }; const store = mockStore({}); // 初始化模拟store的状态 // 如果是异步Thunk,返回Promise让Jest等待执行完成 return store.dispatch(actions.userDispatch(data)).then(() => { // 获取所有被分发的Action const dispatchedActions = store.getActions(); // 验证第一个Action是否符合预期 expect(dispatchedActions[0]).toEqual(expectedAction); }); });
额外:如果只想测试普通Action creator
如果你只是想验证user这个Action creator的正确性,直接测试它就好,不用涉及Thunk:
it("testing user action creator returns correct action", () => { const data = true; const expectedAction = { type: USER, data }; expect(actions.user(data)).toEqual(expectedAction); });
总结一下:普通Action creator直接调用就能拿到Action对象,而Thunk函数需要模拟dispatch环境才能执行内部逻辑,进而验证它分发的Action是否正确。
内容的提问来源于stack exchange,提问作者T R
相关产品推荐
相关产品推荐

