我的 mock server 撒了谎,于是我构建了一个有状态的 API sandbox。

发布: (2026年3月31日 GMT+8 07:26)
6 分钟阅读
原文: Dev.to

Source: Dev.to

FetchSandbox

无状态 Mock 的问题

上个月我在对接一个支付 API。我的测试都是针对一个 mock 服务器编写的,所有测试都通过了,部署到 staging 环境后——整个流程就崩溃了。

mock 告诉我 POST /charges 会返回 {"id": "ch_123"}。的确如此。但随后我的代码会调用 GET /charges/ch_123 来验证状态,而 mock 返回了 404,因为 mock 并没有真正 存储 任何东西。每个请求都生活在各自的宇宙中。

我因此浪费了半天时间。这并不是第一次出现这种情况。

我用过 PrismWireMockMockoon——它们都是很可靠的工具。只要把它们指向一个 OpenAPI 规范,它们就会生成响应,但这些响应都是预设好的。请求之间没有记忆:

POST /customers → 201 {"id": "cust_123"}
GET /customers/cust_123 → 404   # 完全不知道你刚才创建了它

这在你只测试 HTTP 客户端的单元测试中还能工作。但一旦出现多步骤的流程,就会崩溃。

想想真实的 Stripe 集成是怎么运作的:

  1. 创建一个客户
  2. 为该客户创建支付意向 (需要步骤 1 中的客户 ID)
  3. 确认支付意向(需要步骤 2 中的 PI ID)
  4. 触发 webhook(你的服务器需要处理它)

一个 mock 服务器无法完成步骤 2‑4。ID 无法在请求之间传递,webhook 也永远不会触发。你实际上是在测试一个幻想。

我真正需要的

我需要一个沙盒,使得:

  • POST 创建一个真实的资源,我以后可以 GET
  • ID 在请求之间像生产环境一样串联
  • 状态转换正常工作(例如 charge 从 pending 变为 succeeded
  • 当状态变化时触发 Webhook

简而言之——不是一个 mock,而是一个行为像真实 API 的小型伪实现。

我自己做了一个

我已经专注于 FetchSandbox 几个月了。你只需提供一个 OpenAPI 规范,它就会生成一个带有种子数据、状态机和 webhook 事件的有状态沙盒。

npm install -g fetchsandbox

fetchsandbox generate ./stripe-openapi.yaml
# ✓ Sandbox ready: 587 endpoints, 63 seed records

fetchsandbox run stripe --all
# ✓ Accept a payment — 3/3 steps passed
# ✓ Onboard a connected account — 3/3 steps passed
# ✓ Respond to a dispute — 2/2 steps passed
# ✓ All workflows passed — 3/3 (9ms)

run --all 命令正是我一直渴望拥有的功能。它会端到端执行每个集成工作流——创建资源、在步骤之间串联 ID,并验证每个响应。如果出现问题,你可以准确看到是哪一步失败以及原因。

在构建过程中让我惊讶的事

错误场景比成功路径更难处理

我添加了一个 --scenario 标志,这样你就可以将整个 sandbox 切换到 “auth_failure” 模式,观察会发生什么:

fetchsandbox run stripe accept_payment --scenario auth_failure
# ✗ Step 1: POST /v1/payment_intents → 401 Unauthorized
# Scenario "auth_failure" correctly caused failure.
# Scenario reset to default.

我的代码有一个 bug:它没有在 payment‑intent 接口上处理 401,只在 customer 接口上处理了。使用普通的 mock 根本捕捉不到这个问题。

Webhooks 是个陷阱

在真实的 Stripe 集成中,一半的逻辑都在 webhook 处理器里。现在 sandbox 会在资源变更时触发 webhook 事件,你可以实时观察它们:

fetchsandbox webhook-listen stripe
# 12:04:31  payment_intent.created  pi_xyz  → requires_confirmation
# 12:04:32  payment_intent.succeeded pi_xyz → succeeded

检查状态被低估了

运行工作流后,你可以准确看到 sandbox 中的内容:

fetchsandbox state stripe customers
# customers — 3 records
# ┌──────────────┬─────────────────┬──────────┐
# │ id           │ email           │ status   │
# ├──────────────┼─────────────────┼──────────┤
# │ cust_abc123  │ test@acme.com   │ active   │
# └──────────────┴─────────────────┴──────────┘

与其他方案的比较

FeatureMock server (Prism)Vendor sandbox (Stripe test mode)FetchSandbox
Setup time1 min15‑30 min (account + keys)好奇其他人在第三方 API 的测试环境是如何搭建的。

你是全部使用 mock 吗?使用供应商的测试模式?还是混合使用?留下评论——我已经在这个问题上深耕了数月,仍在学习中。

0 浏览
Back to Blog

相关文章

阅读更多 »

用小工具解决 venv 头疼问题?

Python 虚拟环境的问题:Python 的虚拟环境非常棒——但直到你真的尝试使用它们时才会发现问题。每个项目都有自己的 .venv,但……