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

MSW无法捕获Stripe请求问题排查求助

问题:MSW无法捕获Stripe Node.js库的请求,返回真实数据

我尝试在集成测试中使用MSW模拟对Stripe的服务端调用,测试代码如下:

// @vitest-environment node
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { describe, expect, test } from 'vitest';

import {
  mockStripePrices,
  mockStripeProducts,
} from '~/test/mocks/fixtures/stripe';

import { fetchProductsWithPrices } from './billing-helpers.server';

const server = setupServer(
  rest.get('https://api.stripe.com/v1/products', (request, response, context) =>
    response(context.json(mockStripeProducts)),
  ),
  rest.get('https://api.stripe.com/v1/prices', (request, response, context) =>
    response(context.json(mockStripePrices)),
  ),
);

beforeAll(() => server.listen({ onUnhandledRequest: 'warn' }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

describe('fetchProductsWithPrices()', () => {
  test('given nothing: returns all our products and their prices', async () => {
    const actual = await fetchProductsWithPrices();
    const expected = [];

    expect(actual).toEqual(expected);
  });
});

业务代码fetchProductsWithPrices实现如下:

import { stripeAdmin } from './stripe-admin.server';

export async function fetchProductsWithPrices() {
  const [products, prices] = await Promise.all([
    stripeAdmin.products.list({ active: true }),
    stripeAdmin.prices.list({ active: true }),
  ]);

  return products.data.map(product => ({
    ...product,
    prices: prices.data.filter(price => price.product === product.id),
  }));
}

但实际返回的是真实数据而非模拟数据,MSW并未捕获请求。我原以为Node.js Stripe库是REST API的封装,还尝试了GraphQL模拟:

const stripe = graphql.link('https://api.stripe.com/v1/');

但同样无效,请问问题出在哪里?


解答

核心原因

Stripe Node.js SDK默认使用自定义的HTTP请求层(并非Node.js原生的http/https模块),而MSW在Node环境下是通过拦截原生http/https模块或fetch API的请求来工作的,因此默认情况下无法捕获Stripe SDK发出的请求。你尝试的GraphQL模拟方向错误,因为Stripe API是REST架构,并非GraphQL。

解决办法:配置Stripe SDK使用MSW可拦截的HTTP客户端

要让MSW能捕获请求,需要强制Stripe SDK使用fetch API作为请求客户端(MSW支持拦截Node环境下的fetch调用)。具体步骤如下:

  1. 修改Stripe实例的配置(stripe-admin.server.ts):
import Stripe from 'stripe';
// Node.js版本低于18时需安装node-fetch并引入,18+可直接用原生fetch
import fetch from 'node-fetch';

export const stripeAdmin = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: '2024-06-20', // 替换为你的Stripe API版本
  // 仅在测试环境下切换到基于fetch的HTTP客户端
  ...(process.env.NODE_ENV === 'test' ? {
    httpClient: Stripe.createFetchHttpClient({ fetch })
  } : {})
});
  1. 验证MSW拦截逻辑
    你的现有MSW REST请求配置是正确的,无需修改。当Stripe SDK使用fetch发送请求后,MSW就能正常捕获并返回模拟数据。

为什么这样有效?

Stripe SDK提供了createFetchHttpClient方法,允许开发者基于标准fetch API构建自定义客户端。MSW在Node环境中会通过猴子补丁拦截fetch调用,因此只要Stripe SDK使用fetch发送请求,就能被MSW正确拦截并返回你定义的模拟响应。


内容的提问来源于stack exchange,提问作者J. Hesters

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:53:29