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

Recompose的renderComponent在Jest/Enzyme测试中报错问题

解决recompose HOC的Jest/Enzyme测试问题

我来帮你搞定这个测试难题!你的waitForLoad HOC逻辑没问题,测试踩坑大概率是没正确模拟Apollo的状态或者HOC的props传递。下面分场景给你具体的测试方案:

核心思路

我们需要覆盖两种测试场景:

  • 当data.loading为true时,渲染加载组件
  • 当data.loading为false时,渲染被包裹的目标组件

场景1:直接测试HOC的逻辑(无需ApolloProvider)

这种方式最直接,不需要依赖Apollo的上下文,直接给HOC包裹的组件传递模拟的data props:

首先准备测试用的组件和导入依赖:

import React from 'react';
import { shallow } from 'enzyme';
import { waitForLoad } from './path-to-your-hoc';

// 创建一个测试用的目标组件
const TestTargetComponent = () => <div>My Target Content</div>;
// 用HOC包裹测试组件
const WrappedComponent = waitForLoad(TestTargetComponent);

然后写测试用例:

describe('waitForLoad HOC', () => {
  it('显示加载界面当data处于loading状态', () => {
    const wrapper = shallow(<WrappedComponent data={{ loading: true }} />);
    // 断言加载文本存在
    expect(wrapper.text()).toContain('LOADING...');
    // 断言目标组件未渲染
    expect(wrapper.find(TestTargetComponent).exists()).toBe(false);
  });

  it('渲染目标组件当data加载完成', () => {
    const wrapper = shallow(<WrappedComponent data={{ loading: false }} />);
    // 断言目标组件已渲染
    expect(wrapper.find(TestTargetComponent).exists()).toBe(true);
    // 断言加载文本不存在
    expect(wrapper.text()).not.toContain('LOADING...');
  });
});

场景2:结合ApolloProvider的集成测试

如果你的测试需要完整模拟Apollo查询的流程(比如测试真实组件树中的HOC表现),需要用MockedProvider代替真实的ApolloProvider来模拟查询的加载状态:

首先导入MockedProvider(注意版本:新版@apollo/client用@apollo/client/testing,旧版react-apollo用apollo-client/testing):

import { MockedProvider } from '@apollo/client/testing';
import { mount } from 'enzyme';
import YOUR_QUERY from './path-to-your-query';

然后写集成测试用例:

it('在Apollo查询加载时显示加载界面', async () => {
  // 模拟一个会延迟返回结果的查询,用来触发loading状态
  const mocks = [
    {
      request: { query: YOUR_QUERY },
      // 延迟100ms返回结果,模拟真实加载过程
      result: () => new Promise(resolve => setTimeout(() => resolve({ data: {} }), 100)),
    },
  ];

  const wrapper = mount(
    <MockedProvider mocks={mocks} addTypename={false}>
      {/* 这里渲染你的真实业务组件,它内部使用了waitForLoad HOC */}
      <YourBusinessComponent />
    </MockedProvider>
  );

  // 初始状态下,查询处于loading,应该显示加载文本
  expect(wrapper.text()).toContain('LOADING...');

  // 等待查询完成,更新组件
  await new Promise(resolve => setTimeout(resolve, 150));
  wrapper.update();

  // 查询完成后,应该渲染目标组件内容
  expect(wrapper.text()).toContain('My Target Content');
});

常见坑点提示

  • 用shallow测试HOC时,不需要依赖Apollo上下文,直接传递data props即可,更高效
  • 用mount做集成测试时,必须用MockedProvider替代ApolloProvider,否则会报错找不到Apollo客户端
  • 确保你的HOC正确接收了data props——如果是通过Apollo的Query组件注入的,MockedProvider会自动传递包含loading的data对象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:21:32