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上下文,直接传递dataprops即可,更高效 - 用
mount做集成测试时,必须用MockedProvider替代ApolloProvider,否则会报错找不到Apollo客户端 - 确保你的HOC正确接收了
dataprops——如果是通过Apollo的Query组件注入的,MockedProvider会自动传递包含loading的data对象
内容的提问来源于stack exchange,提问作者jorgen
相关产品推荐
相关产品推荐

