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

Dashboard模块测试用例报错:Actions需为纯对象,实际类型为function

问题解决:测试用例中Redux异步Action报错

报错根源

你的组件里调用的getTotalEmployees和getTotalRes是Redux Thunk异步Action(返回函数的类型),但测试代码里创建Redux Store时,没有配置redux-thunk中间件——原生Redux Store只能处理普通对象类型的Action,无法识别函数类型的Action,这就是报错的核心原因。

另外测试里还有两个小问题:

  • 你断言的Action Type和实际代码里的不匹配(实际是FETCH_TOTAL/FETCH_TOTAL_RES,测试里写的是GET_TOTAL_EMPLOYEES/GET_TOTAL_RES)
  • 直接监听React.useEffect的测试方式不够可靠,容易受其他代码干扰

修复步骤

1. 给测试Store添加redux-thunk中间件

项目里肯定已经安装了redux-thunk(前端运行正常),直接在测试代码里导入并配置:

import React from 'react';
import { render, fireEvent, waitForElement } from '@testing-library/react';
import Dashboard from '../Pages/dashboard/Dashboard';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux'; // 新增applyMiddleware
import thunk from 'redux-thunk'; // 导入thunk中间件
import { Router } from 'react-router-dom';
import { createMemoryHistory } from 'history';

const setup = () => {
  // 创建带thunk中间件的Store
  const initialState = {
    employees: {
      employees: [
        { _id: '1', username: 'Employee 1', createdAt: new Date().toJSON() },
        { _id: '2', username: 'Employee 2', createdAt: '2022-12-12T00:00:00.000Z' },
      ],
    },
    results: {
      results: [{ empId: '1', result: 'pass' }],
    },
  };
  
  const store = createStore(
    (state = initialState) => state,
    applyMiddleware(thunk) // 加入thunk,让Store能处理函数型Action
  );

  const history = createMemoryHistory();
  const utils = render(
    <Provider store={store}>
      <Router location={history.location} navigator={history}>
        <Dashboard />
      </Router>
    </Provider>
  );

  return { ...utils, store };
};

2. 修正Action Type的断言

把测试里的期望Type改成和实际代码一致的:

test('getTotalEmployees and getTotalRes actions are dispatched', () => {
  const { store } = setup();
  // 匹配Action里实际dispatch的Type
  expect(store.getActions()).toEqual([
    { type: 'FETCH_TOTAL', payload: '' },
    { type: 'FETCH_TOTAL_RES' },
  ]);
});

3. 优化useEffect的测试方式(可选但更合理)

直接监听React.useEffect不是最佳实践,建议通过跟踪dispatch调用验证逻辑:

test('useEffect dispatches actions on mount and currentId change', () => {
  const mockDispatch = jest.fn();
  // mock useDispatch方法
  jest.spyOn(require('react-redux'), 'useDispatch').mockReturnValue(mockDispatch);
  
  render(
    <Router location={createMemoryHistory().location} navigator={createMemoryHistory()}>
      <Dashboard />
    </Router>
  );

  // 验证初始挂载时调用了两次dispatch
  expect(mockDispatch).toHaveBeenCalledTimes(2);
  // 验证调用的是正确的异步Action函数
  expect(mockDispatch).toHaveBeenCalledWith(expect.any(Function));
  expect(mockDispatch).toHaveBeenCalledWith(expect.any(Function));

  // 清理mock
  require('react-redux').useDispatch.mockRestore();
});

额外优化:Mock异步请求

如果不想测试时触发真实网络请求,可以mock掉API调用:

// 在测试文件顶部mock API模块
jest.mock('../path-to-your-api-module', () => ({
  fetchTotalEmployees: jest.fn().mockResolvedValue({ data: [] }),
  fetchTotalRes: jest.fn().mockResolvedValue({ data: [] }),
}));

这样测试就能正常运行,不会再出现Action类型错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 04:10:36