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

React中Jest+MSW测试GraphQL接口Fetch请求失败排查

排查MSW未拦截GraphQL Fetch请求的常见问题

1. Fetch环境修复是否到位

最初的ReferenceError: fetch is not defined是因为Jest默认Node环境没有内置Fetch API。如果用了node-fetch或whatwg-fetch做兼容,要注意:

  • 若用node-fetch v3+版本,它是ES模块,需在setupTests.js里用require导入,或在Jest配置里设置moduleNameMapper适配
  • 不要同时引入多个Fetch polyfill,避免冲突
  • 确保setupFilesAfterEnv配置正确,把polyfill文件加入Jest的前置执行流程

2. MSW拦截器配置是否生效

检查setupTests.js里的MSW服务启动逻辑:

import { setupServer } from 'msw/node'
import { handlers } from './mocks/handlers'

const server = setupServer(...handlers)

beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())

同时确认拦截器的GraphQL匹配规则正确:

  • GraphQL请求一般是POST方法,URL要和实际请求完全一致
  • 用graphql.query/graphql.mutation匹配时,操作名要和你的Query/Mutation名称完全对应,比如:
    import { graphql } from 'msw'
    
    export const handlers = [
      graphql.query('GetFavorites', (req, res, ctx) => {
        return res(ctx.data({ favorites: [1] }))
      }),
    ]
    
    若没有指定操作名,可临时用graphql.query(/.*/, ...)匹配所有查询,但不推荐长期这么用,容易误拦截。

3. 待测试函数是否正确返回Promise结果

返回undefined大概率是函数没正确返回Promise链。检查你的fetchFavorites:

// 错误示例:未返回Fetch的Promise
const fetchFavorites = () => {
  fetch('/graphql', {
    method: 'POST',
    body: JSON.stringify({ query: 'query GetFavorites { favorites }' }),
    headers: { 'Content-Type': 'application/json' },
  }).then(res => res.json())
}

// 正确示例:返回完整Promise链
const fetchFavorites = () => {
  return fetch('/graphql', {
    method: 'POST',
    body: JSON.stringify({ query: 'query GetFavorites { favorites }' }),
    headers: { 'Content-Type': 'application/json' },
  })
  .then(res => res.json())
  .then(data => data.data.favorites) // 这里要返回预期的[1]
}

用async/await的话,也要确保返回最终结果:

const fetchFavorites = async () => {
  const res = await fetch('/graphql', { /* 请求配置 */ })
  const data = await res.json()
  return data.data.favorites
}

4. 测试用例是否等待Promise完成

如果测试没正确等待Promise,会提前结束并拿到undefined:

// 错误示例:未等待Promise.resolve
test('fetchFavorites returns [1]', () => {
  const result = fetchFavorites()
  expect(result).toEqual([1]) // 此时result是Promise,不是实际返回值
})

// 正确示例1:用async/await
test('fetchFavorites returns [1]', async () => {
  const result = await fetchFavorites()
  expect(result).toEqual([1])
})

// 正确示例2:返回Promise链式调用
test('fetchFavorites returns [1]', () => {
  return fetchFavorites().then(result => {
    expect(result).toEqual([1])
  })
})

5. 排查请求Mock冲突

  • 若之前手动用jest.mock拦截过Fetch,要删除所有相关代码,避免和MSW冲突
  • 确认Create React App的默认Jest配置没覆盖你的自定义配置,比如setupFilesAfterEnv是否正确指向了你的setupTests.js(CRA默认读取src/setupTests.js)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 06:58:30