service-virtualization
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese<objective>
Mock Stripe at the SDK layer and your tests pass green while production 500s the moment Stripe
changes a response field — because the stub was never tied to a contract. This skill picks the
right isolation strategy per dependency (in-process mock, HTTP stub, record-replay, fault
injection, or ephemeral real service), stubs at the HTTP layer so tests survive SDK upgrades, and
makes the CI run fail when any real call escapes the stubs.
</objective>
<objective>
在SDK层Mock Stripe时,你的测试会全部通过,但一旦Stripe修改响应字段,生产环境就会出现500错误——因为Stub从未与契约绑定。本技能针对每个依赖选择合适的隔离策略(进程内Mock、HTTP Stub、记录-重放、故障注入或临时真实服务),在HTTP层进行Stub,确保测试在SDK升级后仍能正常运行,并且当有真实请求绕过Stub时,CI运行会直接失败。
</objective>
Quick Route
快速指南
| Situation | Go to |
|---|---|
| Node/browser test hitting an external HTTP API | MSW → |
| Polyglot CI, complex matching, or you need a standalone stub server | WireMock → |
| Dependency is a DB / cache / queue | Testcontainers → |
| Testing timeouts, latency, connection resets | Toxiproxy → |
| Bootstrapping stubs from a real API, or a multi-step baseline | Record-replay → |
| Wiring any of these into GitHub Actions | |
| Not sure which to reach for | Decision Tree (below) |
| 场景 | 推荐方案 |
|---|---|
| Node/浏览器测试调用外部HTTP API | MSW → |
| 多语言CI、复杂匹配规则,或需要独立Stub服务器 | WireMock → |
| 依赖为数据库/缓存/消息队列 | Testcontainers → |
| 测试超时、延迟、连接重置 | Toxiproxy → |
| 从真实API初始化Stub,或需要多步骤基准 | 记录-重放 → |
| 将上述工具接入GitHub Actions | |
| 不确定选择哪种方案 | 决策树(见下文) |
Discovery Questions
探索问题
Check first — if it exists, use it, respect existing mocking
conventions, and skip anything answered there. Then:
.agents/qa-project-context.md- How many external dependencies does the system call, and which are painful in tests? Rate-limited, slow, flaky, or paid dependencies are the highest-priority virtualization candidates; list payment, email, auth, and third-party data sources.
- What testing levels need isolation? Unit tests want fast in-process mocks; integration tests want HTTP-level stubs; E2E wants real or containerized services — the level sets the strategy.
- Does the provider offer an official test mode or sandbox? Stripe test mode, Twilio test creds, etc. beat any home-grown stub for fidelity — prefer them where they exist.
- Do you have contracts with these dependencies? If yes, contract tests keep stubs in sync;
see . If no, mocking what you don't own is a known risk (Core Principle 3).
contract-testing - Docker available in CI? No Docker steers you to MSW (in-process); Docker unlocks WireMock, Testcontainers, and Toxiproxy.
首先查看——如果存在,请遵循现有Mock约定,并跳过已解答的问题。然后:
.agents/qa-project-context.md- 系统调用多少个外部依赖,其中哪些在测试中存在问题? 受速率限制、缓慢、不稳定或付费的依赖是优先虚拟化的对象;列出支付、邮件、认证和第三方数据源。
- 哪些测试级别需要隔离? 单元测试需要快速的进程内Mock;集成测试需要HTTP层Stub;端到端测试需要真实或容器化服务——测试级别决定策略。
- 服务提供商是否提供官方测试模式或沙箱? Stripe测试模式、Twilio测试凭证等,在保真度上优于任何自制Stub——优先使用此类官方方案。
- 你与这些依赖是否有契约? 如果有,契约测试可保持Stub同步;请查看。如果没有,Mock非自有依赖存在已知风险(核心原则3)。
contract-testing - CI环境中是否支持Docker? 不支持Docker时推荐使用MSW(进程内);支持Docker则可使用WireMock、Testcontainers和Toxiproxy。
Core Principles
核心原则
1. Match the isolation level to the confidence you need. Unit tests can mock aggressively —
they test internal logic. Integration tests should use realistic stubs or real services because
they test boundaries. E2E should run the closest thing to production that is still reliable.
2. Real services beat fakes when they're fast, free, and reliable. A local PostgreSQL
container gives more confidence than a fake and costs little — prefer it. Reserve fakes for
dependencies that are slow, unreliable, or paid.
3. Never mock what you don't own without a contract — and prefer the provider's test mode. If
you stub Stripe and Stripe changes its response shape, your tests stay green while production
breaks. In order of preference: use the provider's official test mode/sandbox (Stripe test mode,
Twilio test creds) → an HTTP stub validated by a contract test for drift → a bare stub only when
nothing better exists. See .
contract-testing4. Stubs must fail realistically. A stub that always returns 200 never exercises error
handling. Every stub needs error variants: 429 rate limits, 500s, timeouts, malformed bodies.
5. One abstraction layer between test and tool. Wrap MSW handlers, WireMock stubs, and
Testcontainers setup behind a consistent interface so switching tools doesn't mean rewriting tests.
1. 隔离级别匹配所需的可信度。 单元测试可大胆使用Mock——它们测试内部逻辑。集成测试应使用贴近真实的Stub或真实服务——它们测试边界。端到端测试应使用最接近生产环境且仍可靠的方案。
2. 若真实服务快速、免费且可靠,优先于Fake服务。 本地PostgreSQL容器比Fake服务更可信,且成本极低——优先选择。仅在依赖缓慢、不稳定或付费时使用Fake服务。
3. 无契约时切勿Mock非自有依赖——优先使用提供商的测试模式。 如果你Stub了Stripe,而Stripe修改了响应结构,测试会通过但生产环境会崩溃。优先级顺序:使用提供商官方测试模式/沙箱(Stripe测试模式、Twilio测试凭证)→ 经契约测试验证防漂移的HTTP Stub → 仅在无更好方案时使用基础Stub。请查看。
contract-testing4. Stub必须模拟真实失败场景。 始终返回200的Stub永远无法触发错误处理逻辑。每个Stub都需要错误变体:429速率限制、500错误、超时、格式错误的响应体。
5. 测试与工具之间保留一层抽象。 将MSW处理器、WireMock Stub和Testcontainers配置封装在统一接口后,切换工具无需重写测试。
Decision Framework
决策框架
When to use each isolation strategy
何时使用每种隔离策略
| Strategy | Speed | Fidelity | Complexity | Best for |
|---|---|---|---|---|
| In-process mock | Fastest | Lowest | Trivial | Unit tests, isolating internal modules |
| HTTP stub (MSW) | Fast | Medium | Low | Frontend/Node tests hitting external APIs |
| HTTP stub (WireMock) | Fast | Medium-High | Medium | Language-agnostic, complex matching rules |
| Record-replay | Fast after first run | High initially, decays | Medium | Bootstrapping stubs from real APIs quickly |
| Service fake | Medium | High | High | Stateful dependencies (in-memory DB, fake auth) |
| Ephemeral real (Testcontainers) | Slower | Highest | Medium | Databases, message queues, caches |
| Shared real service | Slow | Production-level | Low (to set up) | Staging validation, final pre-deploy check |
| 策略 | 速度 | 保真度 | 复杂度 | 最佳适用场景 |
|---|---|---|---|---|
| 进程内Mock | 最快 | 最低 | 极低 | 单元测试、隔离内部模块 |
| HTTP Stub(MSW) | 快 | 中等 | 低 | 前端/Node测试调用外部API |
| HTTP Stub(WireMock) | 快 | 中高 | 中等 | 多语言环境、复杂匹配规则 |
| 记录-重放 | 首次运行后速度快 | 初始保真度高,随时间降低 | 中等 | 快速从真实API初始化Stub |
| 服务Fake | 中等 | 高 | 高 | 有状态依赖(内存数据库、Fake认证) |
| 临时真实服务(Testcontainers) | 较慢 | 最高 | 中等 | 数据库、消息队列、缓存 |
| 共享真实服务 | 慢 | 生产级 | 低(搭建成本) | 预发布验证、最终上线前检查 |
Decision tree
决策树
Is the dependency internal to your codebase?
├─ Yes → In-process mock (vi.mock / jest.mock / monkeypatch)
└─ No → Is it a database, cache, or message queue?
├─ Yes → Testcontainers (ephemeral real instance)
└─ No → Is it a third-party HTTP API?
├─ Yes → Does the provider offer a test/sandbox mode?
│ ├─ Yes → Use sandbox in staging, MSW/WireMock in CI
│ └─ No → MSW or WireMock + contract test for drift detection
└─ No → Is it an internal microservice?
├─ Yes → Contract test (Pact) + stub for consumer tests
└─ No → Evaluate case by caseIs the dependency internal to your codebase?
├─ Yes → In-process mock (vi.mock / jest.mock / monkeypatch)
└─ No → Is it a database, cache, or message queue?
├─ Yes → Testcontainers (ephemeral real instance)
└─ No → Is it a third-party HTTP API?
├─ Yes → Does the provider offer a test/sandbox mode?
│ ├─ Yes → Use sandbox in staging, MSW/WireMock in CI
│ └─ No → MSW or WireMock + contract test for drift detection
└─ No → Is it an internal microservice?
├─ Yes → Contract test (Pact) + stub for consumer tests
└─ No → Evaluate case by caseTools
工具
Pick MSW as the default for in-process Node/browser tests; WireMock for cross-language CI
or standalone stub servers; Prism when the OpenAPI spec is the contract; Mockoon for
dev-time exploratory mocking. Heavy code for each lives in — pointers below.
references/默认选择MSW用于进程内Node/浏览器测试;WireMock用于跨语言CI或独立Stub服务器;Prism适用于以OpenAPI规范为契约的场景;Mockoon用于开发阶段的探索性Mock。各工具详细代码位于——以下为指引。
references/MSW (Mock Service Worker)
MSW (Mock Service Worker)
MSW 2.x intercepts HTTP at the network layer (Service Worker in the browser, request interception
in Node). The default for JS/TS projects. Stub at the HTTP layer (),
never at the SDK method — that decouples the test from the SDK version.
POST /v1/payment_intentsThe strongest enforcement seam this skill offers: .
Set it to in CI so any escaped real call fails the run; is fine locally while
iterating.
setupServer(...).listen({ onUnhandledRequest })"error""warn"See for centralized stateful handlers (payments), the Vitest setup with the
CI/local switch, per-test timeout/retry overrides, and a full stateful auth
flow (create / verify / refresh / revoke via ) keyed on a token.
references/msw.mdonUnhandledRequesthttp.deleteBearerMSW 2.x在网络层拦截HTTP请求(浏览器中使用Service Worker,Node中使用请求拦截)。是JS/TS项目的默认选择。在HTTP层Stub(如),切勿在SDK方法层Stub——这可使测试与SDK版本解耦。
POST /v1/payment_intents本技能提供的最强校验机制:。在CI中设置为,使任何绕过Stub的真实请求导致运行失败;本地迭代时设置为即可。
setupServer(...).listen({ onUnhandledRequest })"error""warn"查看获取集中式有状态处理器(支付场景)、支持CI/本地切换的Vitest配置、测试级超时/重试覆盖,以及基于令牌的完整有状态认证流程(创建/验证/刷新/通过撤销)。
references/msw.mdonUnhandledRequestBearerhttp.deleteWireMock
WireMock
Language-agnostic HTTP stub server (current stable 3.13.2 — 4.0 is beta-only as of mid-2026,
stay on 3.x for CI). Runs standalone or as a Docker container. Best for polyglot environments or
complex matching rules.
Use priority-based mappings for error scenarios: a mapping that matches an
opt-in header () and returns 429 shadows the default happy-path
mapping only when the test asks for it. WireMock also exposes an admin API for programmatic stub
creation (), verification (), and reset
().
priority: 1X-Test-Scenario: rate-limitPOST /__admin/mappingsPOST /__admin/requests/countPOST /__admin/mappings/resetSee for the Docker setup, a response-templated paginated mapping, the
priority error mapping JSON, and the drift-detection seam to (replay a Pact or
validate the stub against the OpenAPI spec via Prism).
references/wiremock.mdcontract-testing跨语言HTTP Stub服务器(当前稳定版为3.13.2——截至2026年中期,4.0仅为测试版,CI环境请使用3.x)。可独立运行或作为Docker容器运行。最适用于多语言环境或复杂匹配规则。
使用基于优先级的映射处理错误场景:优先级为1的映射匹配自定义请求头()并返回429,仅当测试触发时才会覆盖默认成功路径映射。WireMock还提供管理API,用于程序化创建Stub()、验证请求()和重置Stub()。
X-Test-Scenario: rate-limitPOST /__admin/mappingsPOST /__admin/requests/countPOST /__admin/mappings/reset查看获取Docker配置、响应模板化的分页映射、基于优先级的错误映射JSON,以及与的防漂移对接(重放Pact或通过Prism验证Stub与OpenAPI规范一致性)。
references/wiremock.mdcontract-testingOther HTTP mock servers
其他HTTP Mock服务器
| Tool | Strengths | When to use |
|---|---|---|
| Mockoon | Desktop UI + CLI; OpenAPI import; rule-based responses; lightweight | Dev-time mocking and quick CLI mocks in CI |
| Hoverfly | Capture-replay (record real traffic, replay deterministically); capture/simulate/modify/synthesize modes | Migrating from a real dependency to a mock — record once, replay forever |
| Prism | OpenAPI-driven mock server (Stoplight); validates requests + generates responses from spec | OpenAPI-first projects with a published spec |
| MockServer | Java-based; rich expectation matching; multi-protocol | JVM teams already on MockServer |
| 工具 | 优势 | 适用场景 |
|---|---|---|
| Mockoon | 桌面UI+CLI;支持OpenAPI导入;基于规则的响应;轻量 | 开发阶段Mock,以及CI中的快速CLI Mock |
| Hoverfly | 捕获-重放(记录真实流量,确定性重放);支持捕获/模拟/修改/合成模式 | 从真实依赖迁移到Mock的场景——一次记录,永久重放 |
| Prism | OpenAPI驱动的Mock服务器(Stoplight);验证请求并根据规范生成响应 | 采用OpenAPI优先方案且已发布规范的项目 |
| MockServer | 基于Java;丰富的预期匹配;多协议支持 | 已使用MockServer的JVM团队 |
Testcontainers
Testcontainers
Spin up real services in Docker for integration tests — containers start before the suite and
are destroyed after. Use 11.x and friends. Ports are random;
always read them via / , never hardcode 5432/6379.
@testcontainers/postgresqlgetMappedPort()getConnectionUri()See for parallel PostgreSQL + Redis + Elasticsearch startup with
wait strategies, the Vitest wiring (, ),
and the note on refreshing aging image tags ( is behind Elastic 9.x).
references/testcontainers.mdglobalSetupprocess.env.DATABASE_URLtestTimeout: 30_000elasticsearch:8.12.0在Docker中启动真实服务用于集成测试——容器在测试套件启动前启动,测试结束后销毁。使用 11.x及同类库。端口为随机分配;始终通过/读取端口,切勿硬编码5432/6379。
@testcontainers/postgresqlgetMappedPort()getConnectionUri()查看获取PostgreSQL+Redis+Elasticsearch并行启动及等待策略、Vitest配置(、),以及更新过时镜像标签的说明(如已落后于Elastic 9.x)。
references/testcontainers.mdglobalSetupprocess.env.DATABASE_URLtestTimeout: 30_000elasticsearch:8.12.0Toxiproxy (fault injection)
Toxiproxy(故障注入)
ghcr.io/shopify/toxiproxy:2.12.0afterEachSee for the compose port mapping, the wiring (including how the compose / proxy ports map to the real upstream),
the helpers with checks on every call, and a latency + connection-reset usage example.
For broad resilience/game-day work, go to instead.
references/toxiproxy.mdcreateProxy(name, listen, upstream)1543216379response.okchaos-engineeringghcr.io/shopify/toxiproxy:2.12.0afterEach查看获取Compose端口映射、配置(包括Compose中/代理端口如何映射到真实上游服务)、每次调用均包含检查的工具函数,以及延迟+连接重置的使用示例。如需大范围弹性/故障演练,请查看。
references/toxiproxy.mdcreateProxy(name, listen, upstream)1543216379response.okchaos-engineeringRecord-Replay
记录-重放
Record-replay captures real API responses once and replays them deterministically — good for
bootstrapping stubs and for a regression baseline of a multi-step interaction. Implement it with a
record-replay library (Hoverfly, Polly.JS, or VCR-style cassettes), not a hand-rolled
recorder.
It breaks on dynamic data (timestamps, UUIDs), stateful sequences, and age — recordings go stale
within weeks. Always stamp a and fail the test when a recording is older than 30
days, forcing a re-record.
recordedAtSee for the cassette format, the 30-day expiry check,
and a replay harness driving a multi-step flow (create order → add items → apply coupon → checkout).
references/record-replay.mdassertFresh()记录-重放功能会一次性捕获真实API响应,然后确定性地重放——适用于初始化Stub和建立多步骤交互的回归基准。使用记录-重放库(Hoverfly、Polly.JS或VCR风格的磁带)实现,切勿自行编写记录器。
该方案在动态数据(时间戳、UUID)、有状态序列和响应时效性方面存在缺陷——记录内容会在数周内过期。务必添加时间戳,并当记录超过30天时使测试失败,强制重新记录。
recordedAt查看获取磁带格式、 30天过期检查,以及驱动多步骤流程的重放工具(创建订单→添加商品→应用优惠券→结账)。
references/record-replay.mdassertFresh()CI Integration
CI集成
MSW needs zero infrastructure — it intercepts in-process, so CI runs exactly like local; the only
rule is to set in CI (quoted in JS) so an escaped real call
hard-fails the run. WireMock and Testcontainers need Docker.
onUnhandledRequest: error"error"Two incompatible port models coexist and must not be mixed in one suite: the docker-compose
model publishes fixed ports (a hardcoded works), while the
Testcontainers model uses random ports read via and injected into
. Pick one per suite.
DATABASE_URL=...localhost:5432...getMappedPort()process.envSee for the MSW step, the docker-compose GitHub Actions job (, teardown), and the tool-by-constraint table.
references/ci.mdup -d --wait --wait-timeout 120if: always()MSW无需额外基础设施——它在进程内拦截请求,因此CI运行与本地完全一致;唯一规则是在CI中设置(JS中需加引号),使绕过Stub的真实请求直接导致运行失败。WireMock和Testcontainers需要Docker支持。
onUnhandledRequest: "error""error"存在两种不兼容的端口模式,同一测试套件中不可混用:docker-compose模式使用固定端口(硬编码可行),而Testcontainers模式使用随机端口,需通过读取并注入到。每个测试套件仅选择一种模式。
DATABASE_URL=...localhost:5432...getMappedPort()process.env查看获取MSW配置步骤、docker-compose GitHub Actions任务(、清理),以及基于约束条件的工具选择表。
references/ci.mdup -d --wait --wait-timeout 120if: always()Anti-Patterns
反模式
1. Mocking everything
1. 所有依赖全Mock
If every dependency is mocked, your tests verify that your mocks work, not that your system works.
Use real services for databases and caches (via Testcontainers); only stub external HTTP APIs.
如果所有依赖都被Mock,你的测试仅验证Mock是否有效,而非系统是否正常工作。对数据库和缓存使用真实服务(通过Testcontainers);仅对外部HTTP API使用Stub。
2. Inconsistent mock behavior across tests
2. 不同测试中Mock行为不一致
One test stubs Stripe as , another as — now you
have two conflicting versions of reality. Centralize handlers and reuse one response shape across
the whole suite (see the shared shape in ).
{ id: "pi_123" }{ paymentIntentId: "pi_123" }references/msw.md一个测试将Stripe Stub为,另一个测试Stub为——此时你拥有两个相互冲突的现实版本。集中管理处理器,在整个套件中复用同一响应结构(查看中的共享结构)。
{ id: "pi_123" }{ paymentIntentId: "pi_123" }references/msw.md3. Not updating stubs when the API changes
3. API变更时未更新Stub
Your mapping says Stripe returns but the real API now returns
. Tests pass, production fails. Use contract tests to detect
drift — see and the drift seam in .
{ amount: 1000 }{ amount: 1000, currency: "usd" }contract-testingreferences/wiremock.md你的映射显示Stripe返回,但真实API现在返回。测试通过,但生产环境失败。使用契约测试检测漂移——查看和中的防漂移对接。
{ amount: 1000 }{ amount: 1000, currency: "usd" }contract-testingreferences/wiremock.md4. Stubbing the wrong layer
4. Stub错误的层级
Mocking (the SDK method) couples the test to the SDK version. Stub
at the HTTP layer () so the test works regardless of HTTP client or SDK
version.
stripe.paymentIntents.createPOST /v1/payment_intentsMock(SDK方法)会使测试与SDK版本绑定。在HTTP层Stub(),使测试不受HTTP客户端或SDK版本影响。
stripe.paymentIntents.createPOST /v1/payment_intents5. No error-scenario coverage
5. 未覆盖错误场景
Stubs that always return 200 never exercise retry logic, timeout handling, rate-limit backoff, or
error parsing. Every stub needs a corresponding error variant.
始终返回200的Stub永远无法触发重试逻辑、超时处理、速率限制退避或错误解析。每个Stub都需要对应的错误变体。
6. Shared, long-lived mock servers
6. 共享、长期运行的Mock服务器
A shared WireMock instance that multiple CI jobs hit introduces coupling and state leakage. Each
test run starts its own isolated stub server.
多个CI任务共享同一WireMock实例会引入耦合和状态泄漏。每次测试运行都应启动独立的Stub服务器。
7. Record-replay without expiration
7. 记录-重放未设置过期时间
Recordings from six months ago reflect an API that no longer exists. Stamp and fail
the test when recordings exceed 30 days, forcing a re-record (see ).
recordedAtreferences/record-replay.md六个月前的记录反映的是已不存在的API。添加时间戳,当记录超过30天时使测试失败,强制重新记录(查看)。
recordedAtreferences/record-replay.mdVerification
验证
Prove no real call escaped, smallest check first:
bash
undefined验证是否有真实请求泄漏,从最小检查开始:
bash
undefined1. MSW: any unhandled request must hard-fail the suite in CI
1. MSW:CI中任何未处理的请求必须使套件失败
CI=1 npm run test:integration # onUnhandledRequest:"error" → exit 0 means nothing escaped
CI=1 npm run test:integration # onUnhandledRequest:"error" → 退出码0表示无请求泄漏
2. WireMock/Testcontainers: confirm containers are reachable, then teardown leaves nothing
2. WireMock/Testcontainers:确认容器可访问,且清理后无残留
docker compose -f docker-compose.test.yml up -d --wait --wait-timeout 120 && echo OK
docker compose -f docker-compose.test.yml down -v
docker compose -f docker-compose.test.yml up -d --wait --wait-timeout 120 && echo OK
docker compose -f docker-compose.test.yml down -v
3. Grep CI logs for outbound calls to the real provider's host (should print nothing)
3. 在CI日志中搜索真实服务提供商的主机(应无输出)
grep -iE "api.stripe.com|api.twilio.com" ci-run.log && echo "LEAK" || echo "clean"
A green run under `CI=1` with `onUnhandledRequest:"error"` plus an empty grep for the real host is
the proof that the suite ran fully virtualized.
---grep -iE "api.stripe.com|api.twilio.com" ci-run.log && echo "LEAK" || echo "clean"
在`CI=1`且`onUnhandledRequest:"error"`的情况下运行测试通过,且搜索真实服务主机无结果,即可证明套件完全虚拟化运行。
---Done When
完成标准
- A dependency isolation strategy is decided and documented for each external dependency (which get MSW/WireMock stubs, which use Testcontainers, which use the provider's sandbox mode).
- Stubs cover all critical external dependencies with at least one error path each (4xx/5xx, timeout, or rate limit).
- Stubs and mapping files are versioned alongside test code in the same repository.
- The suite runs green in CI with (or the WireMock equivalent), and a grep of CI logs for the real provider host returns nothing.
onUnhandledRequest: "error" - Any record-replay baseline carries a stamp and a 30-day expiry check that fails the test when stale.
recordedAt
- 为每个外部依赖确定并记录隔离策略(哪些使用MSW/WireMock Stub,哪些使用Testcontainers,哪些使用提供商沙箱模式)。
- Stub覆盖所有关键外部依赖,且每个依赖至少包含一条错误路径(4xx/5xx、超时或速率限制)。
- Stub和映射文件与测试代码一同版本化存储在同一仓库中。
- 套件在CI中以(或WireMock等效配置)运行通过,且CI日志中搜索真实服务主机无结果。
onUnhandledRequest: "error" - 所有记录-重放基准均包含时间戳和30天过期检查,过期时测试失败。
recordedAt
Reference Files (in references/
)
references/参考文件(位于references/
)
references/- msw.md — centralized stateful handlers, Vitest setup with the CI/local switch, per-test timeout/retry overrides, and the full create/verify/refresh/revoke auth flow.
onUnhandledRequest - wiremock.md — Docker setup, response-templated and paginated mappings, the priority-based error mapping, the admin API, and the contract-drift seam (Pact/Prism).
- testcontainers.md — parallel PostgreSQL/Redis/Elasticsearch startup, wiring, and the image-tag refresh note.
globalSetup - toxiproxy.md — compose ports, upstream wiring, helpers with
createProxychecks, and a latency + reset usage example.response.ok - record-replay.md — tooling choices, the cassette format, the 30-day check, and a multi-step replay harness.
assertFresh - ci.md — MSW (zero-infra), the docker-compose GitHub Actions job, the two port models, and the tool-by-constraint table.
- msw.md —— 集中式有状态处理器、支持CI/本地切换的Vitest配置、测试级超时/重试覆盖,以及完整的创建/验证/刷新/撤销认证流程。
onUnhandledRequest - wiremock.md —— Docker配置、响应模板化和分页映射、基于优先级的错误映射、管理API,以及与契约测试的防漂移对接(Pact/Prism)。
- testcontainers.md —— PostgreSQL/Redis/Elasticsearch并行启动、配置,以及镜像标签更新说明。
globalSetup - toxiproxy.md —— Compose端口配置、上游服务配置、包含
createProxy检查的工具函数,以及延迟+连接重置的使用示例。response.ok - record-replay.md —— 工具选择、磁带格式、30天检查,以及多步骤重放工具。
assertFresh - ci.md —— MSW配置(无需基础设施)、docker-compose GitHub Actions任务、两种端口模式,以及基于约束条件的工具选择表。
Related Skills
相关技能
- contract-testing — Consumer-driven contract verification with Pact/broker; go there to prove a stub matches a real provider, not just to detect drift against a shared schema.
- test-environments — Full Docker Compose env strategy, preview environments, and seed data; go there for standing up the environment, not for isolating a single dependency.
- chaos-engineering — Broad fault-injection campaigns, game days, and blast-radius limits; go there when resilience itself is the goal rather than making one dependency misbehave in a test.
- api-testing — REST/GraphQL testing patterns, schema validation, and auth flow testing.
- test-data-management — Factory patterns and data seeding for stub state setup.
- contract-testing —— 使用Pact/broker进行消费者驱动的契约验证;如需证明Stub与真实服务匹配(而非仅检测与共享 schema 的漂移),请查看该技能。
- test-environments —— 完整Docker Compose环境策略、预览环境和数据初始化;如需搭建环境而非隔离单个依赖,请查看该技能。
- chaos-engineering —— 大范围故障注入演练、故障日活动和影响范围限制;如需以弹性为目标而非在测试中模拟单个依赖故障,请查看该技能。
- api-testing —— REST/GraphQL测试模式、schema验证和认证流程测试。
- test-data-management —— 用于Stub状态初始化的工厂模式和数据填充。