使用Mock Service Worker(MSW)测试GQL查询的fetch-policy
在MSW测试中验证Apollo useQuery的fetchPolicy参数
由于fetch-policy是Apollo Client的客户端缓存策略,它控制的是Apollo是否从本地缓存读取数据、是否发起网络请求,并不会体现在最终发送到服务器的HTTP请求里——而MSW只是拦截网络请求,所以确实没法直接通过MSW检测这个参数。
下面是两种可靠的验证方式,既能保留MSW的网络请求模拟,又能检测fetchPolicy是否正确传入:
1. Mock useQuery钩子并保留真实请求逻辑
直接拦截useQuery的调用,记录传入的参数,同时调用真实的useQuery保证请求仍走MSW。以Jest为例:
import { useQuery } from '@apollo/client'; import { render } from '@testing-library/react'; import YourComponent from './YourComponent'; // 保存原始useQuery const originalUseQuery = useQuery; // Mock useQuery,同时记录调用参数 jest.mock('@apollo/client', () => ({ ...jest.requireActual('@apollo/client'), useQuery: jest.fn((query, options) => { // 调用真实的useQuery,确保请求正常触发并被MSW拦截 return originalUseQuery(query, options); }), })); test('useQuery使用了正确的fetchPolicy', () => { render(<YourComponent />); // 验证useQuery的调用参数 expect(useQuery).toHaveBeenCalledWith( expect.anything(), // 匹配你的GraphQL查询 expect.objectContaining({ fetchPolicy: 'cache-and-network' // 替换为你需要验证的策略 }) ); });
这种方式简单直接,适合大部分场景,不会影响MSW的正常工作。
2. 自定义Apollo链路拦截请求上下文
通过Apollo的链路(Link)机制,在请求流转过程中读取fetchPolicy参数并记录。这种方式更贴近Apollo的底层逻辑,适合需要全局监测的场景:
import { ApolloClient, InMemoryCache, HttpLink, from, ApolloLink } from '@apollo/client'; import { ApolloProvider } from '@apollo/client/react'; import { render, waitFor } from '@testing-library/react'; import YourComponent from './YourComponent'; // 自定义链路,用于记录fetchPolicy const fetchPolicyRecorderLink = new ApolloLink((operation, forward) => { // 将fetchPolicy挂载到全局(仅测试环境使用) (window as any).__TEST_FETCH_POLICY__ = operation.getContext().fetchPolicy; return forward(operation); }); // 创建带自定义链路的Apollo Client const testClient = new ApolloClient({ cache: new InMemoryCache(), link: from([ fetchPolicyRecorderLink, new HttpLink({ uri: '/graphql' }), // 请求会被MSW拦截 ]), }); test('组件使用了指定的fetchPolicy', async () => { render( <ApolloProvider client={testClient}> <YourComponent /> </ApolloProvider> ); // 等待请求完成后断言 await waitFor(() => { expect((window as any).__TEST_FETCH_POLICY__).toBe('no-cache'); }); });
为什么MSW无法直接检测?
再明确一下:fetchPolicy是Apollo Client内部的逻辑,比如当你设置fetchPolicy: 'cache-first'时,Apollo会直接从本地缓存返回数据,根本不会发起网络请求——MSW连请求都看不到,自然没法检测这个参数。只有通过拦截Apollo Client自身的API或内部流转过程,才能拿到这个参数。
内容的提问来源于stack exchange,提问作者narliecholler
相关产品推荐
相关产品推荐

