![]()
上个月,一位支付工程师在集成Stripe时,测试全部通过,上线就崩。Mock服务器告诉他POST /charges返回{"id": "ch_123"},确实如此。但他的代码接着调用GET /charges/ch_123验证状态,Mock返回404。因为Mock根本不存储任何东西,每个请求活在平行宇宙。
半天时间就这么没了。而且这不是第一次。
Prism、WireMock、Mockoon——这些工具都不错。你丢给它们一个OpenAPI规范,它们生成响应。但响应是罐头的,请求之间没有记忆:
POST /customers → 201 {"id": "cust_123"}
GET /customers/cust_123 → 404 # 完全不知道你刚才创建了什么
这种玩法在单元测试里测HTTP客户端还行。一旦涉及多步骤流程,立刻散架。
想想真实的Stripe集成是怎么工作的:创建PaymentIntent → 确认 → 等待webhook → 更新订单状态。Mock服务器做不了第2到第4步。ID不传递,webhook不触发。你在测试一个幻想。
这位工程师需要的不是Mock,而是一个微型假API,行为像真的一样。他花了三个月做了FetchSandbox。
从"有来无回"到"有始有终"
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命令是他 wished he'd had的东西。它端到端执行每个集成工作流——创建资源、链式传递ID、验证每个响应。出问题的地方,精确到步骤和原因。
错误场景比快乐路径更难搞。他加了--scenario标志,可以把整个沙盒切换到"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:只在customer端点处理401,payment intent端点没处理。普通Mock永远抓不到这个。
Webhooks:那个没人想碰的兔子洞
真实的Stripe集成里,一半逻辑在webhook处理器里。沙盒现在会在资源变更时触发webhook事件,可以实时观看:
fetchsandbox webhook-listen stripe
# 12:04:31 payment_intent.created pi_xyz → requires_confirmation
# 12:04:33 payment_intent.succeeded pi_xyz → succeeded
# 12:04:33 charge.succeeded ch_abc → paid
![]()
这不是装饰。很多集成bug发生在"我以为webhook会在这时触发,但它没有"或者"我处理了错误的事件类型"。沙盒让你看见事件流,而不是猜。
种子数据是另一个被低估的痛点。真实API有状态:你的测试账户里有预设的客户、支付方式、发票。Mock服务器通常给你空数据库,每个测试从零开始建世界。
FetchSandbox的63条种子记录不是随便填的。它们覆盖常见的边缘情况:3D Secure卡、国际地址、不同货币、各种dispute状态。测试时你面对的是真实世界的缩影,而非真空。
状态机:让假API学会"长大"
最微妙的部分是状态转换。真实的PaymentIntent会经历requires_payment_method → requires_confirmation → processing → succeeded。每个状态有合法的下一步,也有非法的跳跃。
Mock服务器通常不管这个。你想把succeeded的PaymentIntent再确认一次?它可能照做,返回200。真实API会扔个错误,告诉你状态机不允许。
FetchSandbox内置了这些状态机。它知道什么时候该拒绝,什么时候该触发webhook,什么时候该让资源"过期"。这不是模拟,是行为克隆。
性能数字也值得一提。上面那个9ms跑完3个工作流,不是噱头。沙盒运行在本地Node进程里,没有网络延迟,没有速率限制。你可以把它塞进CI流水线,每次提交都跑一遍完整集成测试。
对比真实API的测试:Stripe的测试模式有速率限制,某些操作(比如创建Connect账户)需要人工审核模拟,批量跑测试经常触发限流。沙盒把这些摩擦点抹平了。
一个被反复验证的痛点
这位工程师不是第一个被Mock坑的人。Stripe社区论坛里,"为什么我的测试通过但生产环境崩了"是常驻话题。答案通常是:Mock没覆盖那个边缘情况,或者状态不一致。
2023年Stripe自己推出了Stripe Mock,但它是只读的,不支持写操作。写操作的状态管理,至今是开发者自己想办法。
FetchSandbox的野心更大:不只是Stripe,任何有OpenAPI规范的API都能套进去。思路是通用的——状态、种子数据、webhook、场景切换——只是具体的状态机需要针对每个API定制。
目前支持的是Stripe和GitHub API。下一个目标据说是AWS SDK,那个状态空间的复杂度是另一个量级。
开源社区的反应比预期热烈。发布两周,GitHub star数超过Prism同期的三倍。最活跃的issue是请求支持更多API:Twilio、SendGrid、Shopify。
一位早期用户在讨论区留言:「以前我花20%时间写功能,80%时间调集成。现在比例反过来了。」
这个工具会取代Prism们吗?不太可能。单元测试里测HTTP客户端,轻量Mock仍然更顺手。FetchSandbox瞄准的是集成测试的灰色地带——比单元测试重,比端到端测试轻,比真实API快,比Mock真。
那位工程师在README里写了一句很产品经理的话:「我不想测试我的代码能不能发HTTP请求。我想测试我的代码在真实API的行为面前能不能活。」
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.