比较
Mock Service Worker 与类似工具的比较。
为工作选择正确的工具至关重要。我们尽力在下面提供 Mock Service Worker 和其他开源 API 模拟库之间的全面和公正的比较。
¥Choosing the right tool for the job is crucial. We tried our best to provide a comprehensive and unbiased comparison between Mock Service Worker and other open-source API mocking libraries below.
本页的目的不是推断哪种技术更好或更差。这里列出的所有库都有其用武之地,对它们进行评级不仅是主观的,而且对真正应该使用一个而不是另一个的人也是不尊重的。
¥The purpose of this page is not to reason about what technology is better or worse. All the libraries listed here have a place to be, and grading them is not only subjective, but also disrespectful towards the people who really should be using one over another.
比较标准
¥Comparison criteria
任何好的比较都始于一组明确定义的标准。以下是我们在比较 MSW 和其他替代方案时使用的标准(从开发者的角度编写):
¥Any good comparison begins with a clearly defined set of criteria. Here are the criteria we used when comparing MSW to alternatives (written from a developer’s perspective):
-
支持的 API 类型。我可以用库模拟哪些类型的 API?
¥Supported API types. What kinds of API can I mock with the library?
-
环境。我在哪些环境中可以使用该库?
¥Environment. In which environments can I use the library?
-
实现。库如何实现请求拦截?
¥Implementation. How does the library implement request interception?
-
集成。将它集成到我的项目中需要多少努力?
¥Integration. How much effort it takes to integrate it into my project?
-
定义。我如何定义模拟?
¥Definition. How do I define mocks?
Nock
Nock 是一个用于 Node.js 的 HTTP 服务器模拟和期望库。
¥Nock is an HTTP server mocking and expectations library for Node.js.
Nock 是一个很棒的库,用于在 Node.js 中结合 API 模拟和断言。虽然 Mock Service Worker 没有内置断言功能,但它允许你在浏览器和 Node.js 之间无缝重用相同的模拟,并提供一流的 GraphQL 支持和基于标准的请求/响应处理。
¥Nock is a great library for combining API mocking and assertions in Node.js. While Mock Service Worker doesn’t come with a built-in assertion capabilities, it allows you to seamlessly reuse the same mocks across browser and Node.js, as well as providing first-class GraphQL support and standard-based request/response handling.
API 支持
¥API support
API 类型 | Nock | 模拟服务工作者 |
---|---|---|
REST API | ✅ | ✅ |
GraphQL API | ❌ | ✅ |
WebSocket API | ❌ | ✅ |
支持的环境
¥Supported environment
环境 | Nock | 模拟服务工作者 |
---|---|---|
Node.js | ✅ | ✅ |
浏览器 | ❌ | ✅ |
集成
¥Integration
Nock | 模拟服务工作者 |
---|---|
不需要对代码进行任何更改。 | 不需要对代码进行任何更改。 |
需要额外的适配器来拦截特定的请求客户端(例如 axios ) | 适用于任何请求客户端,无需额外配置。 |
定义
¥Definition
Nock
Nock 使用方法链来拦截请求并声明模拟响应:
¥Nock uses method chaining to intercept requests and declare mocked responses:
nock('https://api.example.com').get('/user').reply(200, { id: 1, name: 'John' })
模拟服务工作者
¥Mock Service Worker
MSW 在服务器端路由之后对其拦截 API 进行建模,并根据 Fetch API 规范处理请求和响应,使用你在 JavaScript 中通常使用的相同类:
¥MSW models its interception API after server-side routing and handles requests and responses according to the Fetch API specification, using the same classes you would use normally in JavaScript:
http.get('https://api.example.com/user', async ({ request }) => {
const payload = await request.json()
return HttpResponse.json({ id: 1, name: 'John' })
})
JSON 服务器
¥JSON Server
JSON 服务器 允许你基于 JSON 文件创建实际的 HTTP 服务器。
¥JSON Server allows you to create an actual HTTP server based on a JSON file.
JSON 服务器是一个实际的 HTTP 服务器,它使用抽象响应定义格式。这意味着你必须运行和维护服务器。Mock Service Worker 不会生成任何服务器,因此其初始化成本是免费的。Mock Service Worker 还允许你使用 TypeScript 等语言并从实际后端实现中生成模拟,从而拥有更多防错模拟定义。
¥JSON Server is an actual HTTP server that utilizes abstract response definition format. This means a server you have to run and maintain. Mock Service Worker doesn’t spawn any servers, so its initialization cost is free. Mock Service Worker also allows you to have more error-proof mock definitions by using languages like TypeScript and generating mocks out of the actual backend implementation.
API 支持
¥API support
API 类型 | JSON 服务器 | 模拟服务工作者 |
---|---|---|
REST API | ✅ | ✅ |
GraphQL API | ❌ | ✅ |
WebSocket API | ❌ | ✅ |
支持的环境
¥Supported environment
环境 | JSON 服务器 | 模拟服务工作者 |
---|---|---|
Node.js | ✅ | ✅ |
浏览器 | ✅ X1 | ✅ |
1—JSON 服务器实际上并不在浏览器中运行。由于它是一个独立的服务器,因此可以从系统中的任何位置请求它。
¥1—JSON Server doesn’t actually run in the browser. Since it’s a standalone server, it can be requested from anywhere in your system.
集成
¥Integration
JSON 服务器 | 模拟服务工作者 |
---|---|
需要更改代码以从模拟服务器请求资源。 | 不需要对代码进行任何更改。 |
适用于任何请求客户端,无需额外配置。 | 适用于任何请求客户端,无需额外配置。 |
定义
¥Definition
JSON 服务器
¥JSON Server
JSON 服务器使用资源优先路由格式,隐式生成请求路径并描述模拟响应。
¥JSON Server uses a resource-first routes format that implicitly generates request paths and describes mocked responses.
{
"posts": [
{ "id": 1, "title": "json-server" },
{ "id": 2, "title": "mock-service-worker" }
]
}
这将根据描述的资源自动生成服务器端路由,如
GET /posts
和DELETE /posts/:index
。此类路由的性质是静态的,需要额外的抽象才能实现更复杂的网络行为。¥This will automatically generate server-side routes like
GET /posts
andDELETE /posts/:index
based on the described resources. The nature of such routes is static and requires additional abstractions to achieve more complex network behaviors.
模拟服务工作者
¥Mock Service Worker
MSW 在服务器端路由之后对其拦截 API 进行建模,并根据 Fetch API 规范处理请求和响应,使用你在 JavaScript 中通常使用的相同类:
¥MSW models its interception API after server-side routing and handles requests and responses according to the Fetch API specification, using the same classes you would use normally in JavaScript:
http.get('/posts', () => {
return HttpResponse.json([
{ id: 1, title: 'json-server' },
{ id: 2, title: 'mock-service-worker' },
])
})
使用 MSW,你必须明确定义服务器端操作,如
http.get('/posts')
或http.delete('/posts/:index')
。MSW 优先考虑显式性,利用编程请求解析,允许更复杂的网络行为。¥With MSW, you have to explicitly define server-side operations like
http.get('/posts')
orhttp.delete('/posts/:index')
. MSW prioritized explicitness, taking advantage of programmatic request resolution, allowing for more complex network behaviors.
Mirage
Mirage 是一个 API 模拟库,可让你构建、测试和共享完整的 JavaScript 应用,而无需依赖任何后端服务。
¥Mirage is an API mocking library that lets you build, test and share a complete working JavaScript application without having to rely on any backend services.
Mirage 以数据建模为中心,以模拟更复杂的服务器行为。Mock Service Worker 没有内置数据建模功能,而是在名为
@mswjs/data
的单独包中公开它们。这样,你可以在需要时将建模带到桌面上。¥Mirage is centered around data modeling to emulate more complex server behaviors. Mock Service Worker doesn’t come with a built-in data modeling capabilities and instead exposes them in a separate package called
@mswjs/data
. This way you can bring modeling to the table once you need it.
API 支持
¥API support
API 类型 | Mirage | 模拟服务工作者 |
---|---|---|
REST API | ✅ | ✅ |
GraphQL API | ❌ | ✅ |
WebSocket API | ❌ | ✅ |
支持的环境 =
¥Supported environments
环境 | Mirage | 模拟服务工作者 |
---|---|---|
Node.js | ❌ | ✅ |
浏览器 | ✅ | ✅ |
实现
¥Implementation
环境 | Mirage | 模拟服务工作者 |
---|---|---|
浏览器 | Monkey-patches fetch 和 XMLHttpRequest (使用 pretender )。 | 使用服务工作线程在浏览器级别拦截请求。 |
集成
¥Integration
Mirage | 模拟服务工作者 |
---|---|
不需要对代码进行任何更改。 | 不需要对代码进行任何更改。 |
适用于任何请求客户端,无需额外配置。 | 适用于任何请求客户端,无需额外配置。 |
定义
¥Definition
Mirage
Mirage 使用路由处理程序格式来定义类似服务器的路由和模拟响应。
¥Mirage uses route handlers format to define server-like routes and mocked responses.
createServer({
routes() {
this.get('/movies', () => {
return ['Interstellar', 'Inception', 'Dunkirk']
})
},
})
Mirage 还带有一个内存数据库,可帮助你建模更复杂的数据关系。
¥Mirage also comes with an in-memory database to help you model more complex data relationships.
createServer({
models: {
movie: Model.extend({
castMembers: hasMany(),
}),
castMember: Model.extend({
movie: belongsTo(),
}),
},
routes() {
// Your route handlers responding with the data.
},
})
模拟服务工作者
¥Mock Service Worker
MSW 在服务器端路由之后对其拦截 API 进行建模,并根据 Fetch API 规范处理请求和响应,使用你在 JavaScript 中通常使用的相同类:
¥MSW models its interception API after server-side routing and handles requests and responses according to the Fetch API specification, using the same classes you would use normally in JavaScript:
http.get('/movies', () => {
return HttpResponse.json(['Interstellar', 'Inception', 'Dunkirk'])
})
尽管 MSW 没有提供内置的数据建模功能,但它利用生态系统包(如 @mswjs/data
)为你提供数据优先的 API 模拟方法(如果你选择的话)。
¥Although MSW doesn’t ship data modeling capabilities built-in, it leverages ecosystem packages, like @mswjs/data
, to give you a data-first approach to API mocking if you choose it.
import { factory, primaryKey, oneOf, manyOf } from '@mswjs/data'
// Model the data.
const db = factory({
movie: {
id: primaryKey(randomUuid),
title: String,
castMembers: manyOf('castMember'),
},
castMember: {
id: primaryKey(randomUuid),
name: String,
movie: oneOf('movie'),
},
})
// Generate request handlers based on the models.
// - GET /movies
// - GET /movies/:id
// - POST /movies
// - ...
db.toHandlers('rest')
// Including GraphQL queries!
// - query ListMovies
// - query GetMovie
// - mutation AddMovie
// - ...
db.toHandlers('graphql')
Cypress - cy.intercept()
Cypress 是一个端到端测试框架,通过其 cy.intercept()
API 提供 API 模拟功能。
¥Cypress is an end-to-end testing framework that provides API mocking capabilities through its cy.intercept()
API.
API 支持
¥API support
API 类型 | cy.intercept() | 模拟服务工作者 |
---|---|---|
REST API | ✅ | ✅ |
GraphQL API | ❌ X1 | ✅ |
WebSocket API | ❌ | ✅ |
1—尽管可以通过自定义别名处理 GraphQL 请求,但仍需要大量额外设置。Cypress 通过 HTTP 处理实现 GraphQL API 模拟(因为 GraphQL 最常在 Web 上通过 HTTP 实现),而不是一流的 GraphQL 支持。
¥1—Although it is possible to work with GraphQL requests through custom aliasing, it still requires a lot of additional setup. Cypress achieves GraphQL API mocking through HTTP handling (since GraphQL is most commonly implemented over HTTP on the web) instead of a first-class GraphQL support.
支持的环境 =
¥Supported environments
API 类型 | cy.intercept() | 模拟服务工作者 |
---|---|---|
Node.js | ❌ X1 | ✅ |
浏览器 | ✅ | ✅ |
1—Cypress 是一个浏览器测试框架,这意味着你不能在 Node.js 进程中使用
cy.intercept()
模拟,例如集成测试或后端应用。¥1—Cypress is a browser testing framework, which means you cannot use your
cy.intercept()
mocks in a Node.js process, like an integration test or a backend application.
实现
¥Implementation
环境 | cy.intercept() | 模拟服务工作者 |
---|---|---|
浏览器 | 使用浏览器范围的 HTTP 代理通过 Cypress 作为其运行时的一部分生成的自定义服务器路由传出请求。 | 使用服务工作线程在浏览器级别拦截请求。 |
集成
¥Integration
cy.intercept() | 模拟服务工作者 |
---|---|
不需要更改代码。Cypress 原生可用。 | 不需要更改代码。 |
适用于任何请求客户端,无需额外配置。 | 适用于任何请求客户端,无需额外配置。 |
定义
¥Definition
cy.intercept()
Cypress 使用自定义匹配器签名和路由处理程序函数来拦截和处理请求。它利用自定义方法(如 req.reply()
、req.continue()
或 req.redirect()
)进行更详细的请求控制。
¥Cypress uses a custom matcher signature and a route handler function to intercept and handle requests. It utilizes custom methods like req.reply()
, req.continue()
or req.redirect()
for more detailed request control.
cy.intercept('POST', '/users', {
statusCode: 201,
body: req.body,
delay: 100,
})
模拟服务工作者
¥Mock Service Worker
MSW 在服务器端路由之后对其拦截 API 进行建模,并根据 Fetch API 规范处理请求和响应,使用你在 JavaScript 中通常使用的相同类:
¥MSW models its interception API after server-side routing and handles requests and responses according to the Fetch API specification, using the same classes you would use normally in JavaScript:
import { http, delay } from 'msw'
http.post('/users', async ({ request }) => {
// Read the request body as you would normally.
const user = await request.json()
// Control the response resolver execution flow
// via Promises, like this "delay" Promise below.
await delay(100)
// Construct a response as you would normally.
return HttpResponse.json(user, { status: 201 })
})
MSW 通过其 passthrough()
和 bypass()
API 为你提供对请求的更高级控制,这些 API 仍然会在后台产生语义 HTTP 响应。
¥MSW gives you a more advanced control over the requests through its passthrough()
and bypass()
APIs, which still yield semantic HTTP responses under the hood.
Playwright - page.route()
Playwright 是一个浏览器测试工具,它通过其 page.route()
API 提供 API 模拟功能。
¥Playwright is a browser testing tool that provides API mocking capabilities through its page.route()
API.
API 支持
¥API support
API 类型 | page.route() | 模拟服务工作者 |
---|---|---|
REST API | ✅ | ✅ |
GraphQL API | ❌ X1 | ✅ |
WebSocket API | ✅ | ✅ |
1—你可以使用
page.route()
处理 GraphQL 请求,因为它们也是 HTTP 请求,但 Playwright 不提供对模拟 GraphQL API 的一流支持。¥1—You can handle GraphQL requests with
page.route()
since they are also HTTP requests but Playwright does not provide a first-class support for mocking GraphQL APIs.
支持的环境 =
¥Supported environments
API 类型 | page.route() | 模拟服务工作者 |
---|---|---|
Node.js | ❌ X1 | ✅ |
浏览器 | ✅ | ✅ |
1—尽管使用 Playwright 你可以在 Node.js 中编写测试,但 Playwright 本身(及其
page.route()
)只会影响生成的浏览器中的流量,而不会影响 Node.js 进程。¥1—Although with Playwright you write your tests in Node.js, Playwright itself (and its
page.route()
) only affect the traffic in the spawned browser, not the Node.js process.
实现
¥Implementation
环境 | page.route() | 模拟服务工作者 |
---|---|---|
浏览器 | 使用 Chrome DevTools 协议 在浏览器级别拦截请求。 | 使用服务工作线程在浏览器级别拦截请求。 |
集成
¥Integration
page.route() | 模拟服务工作者 |
---|---|
不需要对代码进行任何更改。Playwright 原生可用。 | 不需要对代码进行任何更改。 |
适用于任何请求客户端,无需额外配置。 | 适用于任何请求客户端,无需额外配置。 |
定义
¥Definition
page.route()
Playwright 中的 page.route()
函数利用 route.fulfill()
和 route.continue()
等自定义方法让你更好地控制请求。
¥The page.route()
function in Playwright utilizes custom methods like route.fulfill()
and route.continue()
to give you more control over the request.
page.route('/fruits', async (route) => {
const request = route.request()
if (request.method === 'POST') {
const response = await route.fetch()
const json = await response.json()
json.push({ name: 'Playwright' })
return route.fulfill({ response, json })
}
route.continue()
})
模拟服务工作者
¥Mock Service Worker
import { bypass } from 'msw'
http.post('/fruits', async ({ request }) => {
const response = await fetch(bypass(request))
const json = await response.json()
json.push({ name: 'Mock Service Worker' })
return HttpResponse.json(json, response)
})
MSW 中
route.continue()
的替代方案是从响应解析器中不返回任何内容。但由于我们可以将请求拦截范围缩小到方法(POST
)和路径(/fruits
),我们的请求处理程序永远不会关注其他请求。¥The alternative for
route.continue()
in MSW is simply returning nothing from a response resolver. But since we can narrow down the request interception to both the method (POST
) and path (/fruits
), our request handler never concerns itself with other requests.
MSW 使用自定义 bypass()
函数封装任何给定的 Request
实例,以防止它受到任何其他匹配的请求处理程序的影响。
¥MSW uses the custom bypass()
function that wraps any given Request
instance to prevent it from being affected by any other otherwise matching request handlers.