Jest测试withApollo组件报错找不到client,浏览器运行正常的解决方案
解决Jest测试中withApollo找不到client的问题
这个问题我之前帮人排查过很多次啦,本质就是测试环境里你的组件没有处在Apollo Client的上下文当中——浏览器里正常运行是因为你整个应用的根组件已经被<ApolloProvider>包裹了,但单独测试ParentComponent时,这个上下文就缺失了,所以withApollo找不到client。
下面给你两种实用的解决思路,按需选择:
方法一:用Mock Apollo Client包裹测试组件
适合只是想让组件正常渲染、不需要模拟具体GraphQL请求的场景:
- 先创建一个mock的Apollo Client实例
可以单独写个测试工具文件(比如test-utils.js),也直接写在测试文件里:
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client'; // 创建一个极简的mock client,不需要真实请求地址 const mockApolloClient = new ApolloClient({ uri: 'https://test.example.com/graphql', // 随便填个测试用的地址就行 cache: new InMemoryCache(), });
- 在测试中用
<ApolloProvider>包裹你要挂载的组件
修改你的测试代码:
import { mount } from 'enzyme'; import { ApolloProvider } from '@apollo/client'; import ParentComponent from './ParentComponent'; import { mockApolloClient } from './test-utils'; describe('ParentComponent测试', () => { it('能正常渲染不报错', () => { const wrapper = mount( <ApolloProvider client={mockApolloClient}> <ParentComponent /> </ApolloProvider> ); // 这里可以加你的断言逻辑,比如判断组件是否渲染成功 }); });
方法二:用MockedProvider模拟GraphQL请求
如果需要测试组件的GraphQL查询/突变逻辑,推荐用@apollo/client/testing提供的MockedProvider,可以精准模拟请求返回:
- 导入MockedProvider并定义请求mock
import { MockedProvider } from '@apollo/client/testing'; import { mount } from 'enzyme'; import ParentComponent from './ParentComponent'; // 导入组件里用到的GraphQL查询 import { YOUR_QUERY } from './your-queries'; // 模拟查询的请求和返回数据 const mocks = [ { request: { query: YOUR_QUERY, variables: { /* 你的查询变量,如果有的话 */ }, }, result: { data: { /* 模拟返回的业务数据 */ }, }, }, ];
- 用MockedProvider包裹组件并测试
describe('ParentComponent数据渲染测试', () => { it('能正确渲染请求回来的数据', async () => { const wrapper = mount( <MockedProvider mocks={mocks} addTypename={false}> <ParentComponent /> </MockedProvider> ); // 等待mock请求完成并更新组件 await new Promise(resolve => setImmediate(resolve)); wrapper.update(); // 这里添加断言,比如判断数据是否渲染到页面上 }); });
额外优化:封装重复逻辑
如果多个测试用例都需要包裹Apollo上下文,可以把包裹逻辑抽成工具函数,减少重复代码:
// test-utils.js import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client'; import { mount } from 'enzyme'; const createMockClient = () => new ApolloClient({ uri: 'https://test.example.com/graphql', cache: new InMemoryCache(), }); export const mountWithApollo = (component) => { const client = createMockClient(); return mount( <ApolloProvider client={client}> {component} </ApolloProvider> ); };
之后测试里直接用:
import { mountWithApollo } from './test-utils'; it('正常渲染', () => { const wrapper = mountWithApollo(<ParentComponent />); });
内容的提问来源于stack exchange,提问作者Dreak441
相关产品推荐
相关产品推荐

