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

Jest测试React setState钩子时返回[function anonymous]问题排查

问题原因分析

你看到setState接收的是匿名函数,说明你的Sidebar组件里用了函数式的setState更新器(这是React中依赖前状态更新的标准写法),而你的测试代码却直接断言它被调用时传入了一个对象,自然不匹配。

比如你的Sidebar组件里的点击逻辑大概率是这样的:

const handleButtonClick = () => {
  setState(prevState => ({
    ...prevState,
    status: 'ok',
    count: prevState.count + 1
  }));
};

这种情况下,setState实际接收的是一个匿名函数,而不是直接的状态对象。

测试代码修正方案

你需要在测试中获取到这个更新函数,手动调用它并传入模拟的初始状态,再断言返回的结果是否符合预期。具体步骤如下:

  1. 保留对setState的mock,渲染组件并触发点击事件
  2. 从mock的调用记录中提取出传入的更新函数
  3. 调用该函数并传入初始的mock state,得到更新后的状态
  4. 断言更新后的状态是否匹配预期值

修正后的测试代码示例:

import { render, screen, fireEvent } from '@testing-library/react';
import Sidebar from './Sidebar';

test('点击按钮后正确更新状态', () => {
  const mockSetState = jest.fn();
  const mockInitialState = { status: 'idle', count: 0 };

  // 渲染Sidebar组件,传入mock的state和setState
  render(<Sidebar state={mockInitialState} setState={mockSetState} />);
  
  // 触发按钮点击
  fireEvent.click(screen.getByRole('button'));

  // 获取setState被调用时传入的更新函数
  const stateUpdater = mockSetState.mock.calls[0][0];
  // 调用更新函数,传入初始状态,得到更新后的状态
  const updatedState = stateUpdater(mockInitialState);

  // 断言更新后的状态是否符合预期
  expect(updatedState).toEqual({ status: 'ok', count: 1 });
  // 可选:断言setState确实被调用了一次,且参数是函数类型
  expect(mockSetState).toHaveBeenCalledTimes(1);
  expect(mockSetState).toHaveBeenCalledWith(expect.any(Function));
});
额外说明

如果你的Sidebar组件本来应该直接传入对象式的setState(比如状态更新不依赖前状态),那你需要检查组件代码,确认是否误写为函数式。但从count更新的逻辑来看,用函数式更新是更安全的做法,因为它能确保基于最新的状态进行更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 04:01:14