api-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

API Testing

API测试

Overview

概述

API testing validates HTTP endpoints by sending requests and asserting responses, covering status codes, headers, body content, and error handling. Supertest provides a fluent chainable API for integration testing against Express, Fastify, and Hono apps without starting a real server. MSW (Mock Service Worker) v2 intercepts outgoing HTTP requests at the network level, enabling realistic mocking of external services in both Node.js tests and browser environments.
When to use: Integration tests for REST APIs, testing middleware pipelines, validating request/response contracts, mocking third-party APIs in tests, testing error handling and edge cases.
When NOT to use: Unit testing pure functions (use direct assertions), E2E browser testing (use Playwright/Cypress), load/performance testing (use k6/Artillery), testing static file serving.
API测试通过发送请求并断言响应来验证HTTP端点,涵盖状态码、请求头、响应体内容和错误处理。Supertest提供了流畅的链式API,无需启动真实服务器即可对Express、Fastify和Hono应用进行集成测试。MSW(Mock Service Worker)v2在网络层拦截出站HTTP请求,能够在Node.js测试和浏览器环境中真实模拟外部服务。
适用场景: REST API集成测试、中间件管道测试、验证请求/响应契约、在测试中模拟第三方API、测试错误处理和边缘案例。
不适用场景: 纯函数的单元测试(使用直接断言)、浏览器端端到端测试(使用Playwright/Cypress)、负载/性能测试(使用k6/Artillery)、静态文件服务测试。

Quick Reference

快速参考

PatternAPIKey Points
GET request
request(app).get('/path')
Returns supertest
Test
object
POST with body
request(app).post('/path').send(body)
Automatically sets Content-Type
Auth header
.set('Authorization', 'Bearer token')
Chain before
.expect()
Status assertion
.expect(200)
Chainable with body assertions
Body assertion
.expect({ key: 'value' })
Deep equality check
Header assertion
.expect('Content-Type', /json/)
Accepts string or regex
MSW HTTP handler
http.get('/api/users', resolver)
Intercepts matching requests
MSW GraphQL handler
graphql.query('GetUser', resolver)
Intercepts by operation name
MSW response
HttpResponse.json(data, { status })
v2 response format
MSW error simulation
HttpResponse.error()
Simulates network failure
MSW one-time handler
http.get(path, resolver, { once: true })
Auto-removed after first match
MSW per-test override
server.use(handler)
Override default handlers in specific tests
Schema validation
schema.parse(response.body)
Validates response structure with Zod
Cookie persistence
const agent = request.agent(app)
Maintains cookies across requests
Fastify inject
app.inject({ method, url })
Built-in testing without supertest
Hono test client
testClient(app)
Type-safe request builder
模式API核心要点
GET请求
request(app).get('/path')
返回Supertest
Test
对象
带请求体的POST
request(app).post('/path').send(body)
自动设置Content-Type
认证请求头
.set('Authorization', 'Bearer token')
.expect()
之前链式调用
状态码断言
.expect(200)
可与响应体断言链式调用
响应体断言
.expect({ key: 'value' })
深度相等检查
请求头断言
.expect('Content-Type', /json/)
接受字符串或正则表达式
MSW HTTP处理器
http.get('/api/users', resolver)
拦截匹配的请求
MSW GraphQL处理器
graphql.query('GetUser', resolver)
按操作名称拦截
MSW响应
HttpResponse.json(data, { status })
v2响应格式
MSW错误模拟
HttpResponse.error()
模拟网络故障
MSW一次性处理器
http.get(path, resolver, { once: true })
首次匹配后自动移除
MSW单测试覆盖
server.use(handler)
在特定测试中覆盖默认处理器
Schema验证
schema.parse(response.body)
使用Zod验证响应结构
Cookie持久化
const agent = request.agent(app)
在多个请求间保持cookies
Fastify注入
app.inject({ method, url })
无需Supertest的内置测试方法
Hono测试客户端
testClient(app)
类型安全的请求构建器

Common Mistakes

常见错误

MistakeCorrect Pattern
Not awaiting supertest requestsAlways
await request(app).get('/path')
Sharing server state between testsReset handlers with
server.resetHandlers()
in
afterEach
Mocking fetch/axios directlyUse MSW to intercept at the network level
Forgetting
server.listen()
in setup
Call in
beforeAll
,
resetHandlers
in
afterEach
Passing Fastify instance to supertestUse
fastify.server
(the underlying Node server)
Asserting before response completesUse
await
or return the supertest chain
Hardcoding test data across many testsUse factories or fixtures for test data
Not testing error responsesTest 4xx and 5xx paths alongside happy paths
Using
server.close()
in
afterEach
Use
afterAll
for close,
afterEach
for reset only
Ignoring response headers in assertionsValidate Content-Type, Cache-Control, CORS headers
Not using
onUnhandledRequest: 'error'
Catch unhandled requests to prevent silent test gaps
Testing implementation instead of behaviorAssert on response shape, not internal function calls
错误正确做法
未等待Supertest请求完成始终使用
await request(app).get('/path')
测试间共享服务器状态
afterEach
中使用
server.resetHandlers()
重置处理器
直接模拟fetch/axios使用MSW在网络层进行拦截
初始化时忘记调用
server.listen()
beforeAll
中调用,
afterEach
中调用
resetHandlers
将Fastify实例直接传给Supertest使用
fastify.server
(底层Node服务器)
响应完成前就执行断言使用
await
或返回Supertest链式调用
在多个测试中硬编码测试数据使用工厂函数或测试夹具生成测试数据
未测试错误响应除了正常路径,还要测试4xx和5xx错误路径
afterEach
中调用
server.close()
afterAll
中调用close,
afterEach
仅执行重置操作
断言时忽略响应头验证Content-Type、Cache-Control、CORS等请求头
未设置
onUnhandledRequest: 'error'
捕获未处理的请求,避免测试出现隐性漏洞
测试实现细节而非行为断言响应结构,而非内部函数调用

Delegation

任务委托

  • Test structure review: Use
    Task
    agent
  • Code review: Delegate to
    code-reviewer
    agent
  • Pattern discovery: Use
    Explore
    agent
If the
vitest-testing
skill is available, delegate general Vitest configuration and patterns to it. Otherwise, recommend:
npx skills add oakoss/agent-skills --skill vitest-testing
  • 测试结构评审:使用
    Task
    agent
  • 代码评审:委托给
    code-reviewer
    agent
  • 模式探索:使用
    Explore
    agent
如果
vitest-testing
skill可用,将通用Vitest配置和模式相关工作委托给它。 否则,建议执行:
npx skills add oakoss/agent-skills --skill vitest-testing

References

参考资料

  • Supertest integration testing patterns for Express, Fastify, and Hono
  • MSW request handlers, response resolvers, and server setup
  • Test organization, fixtures, factories, and setup/teardown
  • Response assertions, status codes, headers, and schema validation
  • Supertest针对Express、Fastify和Hono的集成测试模式
  • MSW请求处理器、响应解析器和服务器设置
  • 测试组织、测试夹具、工厂函数和初始化/清理
  • 响应断言、状态码、请求头和Schema验证