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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:55:17