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

如何测试React useEffect钩子内调用的react-router push方法参数正确性

测试代码存在的3个核心问题
    1. 未实际执行组件渲染:你只声明了render函数,没有调用它,组件从未初始化,自然不会触发useEffect逻辑
    1. 测试的是高阶组件包裹后的实例:你默认导出的组件是经过withRouter、aCustomHigherOrderC两层HOC包裹后的产物,shallow渲染只会渲染最外层的HOC容器,不会触发内部真实MyComponent的逻辑
    1. 断言参数与实际传参不匹配:组件内push方法接收的是一个包含pathname、search属性的对象,你的断言里传入的是拼接后的字符串,就算push被触发也会断言失败
正确测试方案

第一步:修改组件导出,暴露未被HOC包裹的原始组件

给业务组件增加命名导出,测试时直接测原始组件即可,HOC的逻辑可以单独验证,不需要耦合在组件单测里:

import React from 'react';
import { compose } from 'redux';
import { withRouter } from 'react-router';

// 增加命名导出,专门用于测试
export const MyComponent = ({
  router: { push, location },
}) => {
    const version = 'v2';
  React.useEffect(() => {
    push({
      pathname: `/${version}/new_path`,
      search: location.search ? location.search: '',
    });
  }, []);
  return <div>Sample div text</div>
};

const higherOrder = compose(
  withRouter,
  aCustomHigherOrderC,
);

export default higherOrder(MyComponent);

第二步:修改测试代码

import React from 'react';
import { shallow } from 'enzyme';
// 导入未被HOC包裹的原始组件
import { MyComponent } from '../src/components/MyComponent';

const props = {
  router: {
    push: jest.fn(),
    location: {
      search: '?param=1',
    },
  },
};

describe('MyComponent component tests', () => {
  it('should push correct route when mounted', () => {
    // 直接渲染组件
    shallow(<MyComponent {...props} />);
    // 断言参数和组件内实际传参结构一致
    expect(props.router.push).toHaveBeenCalledWith({
      pathname: '/v2/new_path',
      search: '?param=1'
    });
    // 也可以额外验证拼接后的完整路径
    const calledParams = props.router.push.mock.calls[0][0];
    expect(`${calledParams.pathname}${calledParams.search}`).toBe('/v2/new_path?param=1');
  });
});
补充说明

如果你的项目要求必须测试经过HOC包裹的默认导出组件,可以把shallow改成mount完整渲染整个组件树,同时要给withRouter提供外层的Router上下文,不过这种方式会增加单测复杂度,更推荐直接测试原始组件的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:48:02