MSW 2.0终于来了!🎉 阅读发布说明,请按照迁移指南进行升级。如果在升级过程中有任何问题,请在我们的Discord服务器上联系我们。
我们还录制了迄今为止最全面的MSW介绍。在我们的官方视频课程中学习如何像专业人士一样模拟API:
Mock Service Worker
Mock Service Worker (MSW) 是一个适用于浏览器和Node.js的无缝REST/GraphQL API模拟库。
特性
- 无缝集成。为您提供专用的请求拦截层。使您的应用程序代码和测试不知道是否有模拟。
- 无偏差。请求相同的生产资源并测试应用程序的实际行为。增强现有API,或在没有API的情况下边设计边使用。
- 熟悉且强大。使用类似Express的路由语法来拦截请求。使用参数、通配符和正则表达式匹配请求,并以必要的状态码、标头、cookie、延迟或完全自定义的解析器进行响应。
"我发现了MSW,非常兴奋,因为不仅我仍然可以在DevTools中看到模拟的响应,而且这些模拟不必写在Service Worker中,而可以与应用程序的其他部分放在一起。这使得采用变得非常容易。我还可以将其用于测试,这使MSW成为一个巨大的生产力提升工具。"
文档
本README将简要介绍该库,但开始使用Mock Service Worker的最佳地点莫过于其官方文档。
示例
- 查看使用示例列表
浏览器
工作原理
在浏览器中的使用是Mock Service Worker与其他工具的区别所在。利用Service Worker API(可以出于缓存目的拦截请求),Mock Service Worker在网络层面用您的模拟定义响应被拦截的请求。这样,您的应用程序对模拟一无所知。
看看这个关于Mock Service Worker在浏览器中如何工作的快速演示:
有何不同?
- 该库在网络层面拦截请求,这意味着是在请求已经执行并"离开"您的应用程序之后。因此,您的全部代码都会运行,在模拟时给您更多信心;
- 想象您的应用程序是一个盒子。市面上的每个API模拟库都会打开您的盒子,移除发出请求的部分,用一个黑盒代替。Mock Service Worker保持您的盒子完整,与生产环境中的一模一样。相反,MSW存在于您的盒子旁边的一个单独的盒子中;
- 不再需要stub
fetch
、axios
、react-query
等; - 您可以在单元测试、集成测试和E2E测试中重用相同的模拟定义。我们是否提到过本地开发和调试?没错。所有这些都针对相同的网络描述运行,无需适配器或臃肿的配置。
使用示例
// src/mocks.js
// 1. 导入库。
import { http, HttpResponse } from 'msw'
import { setupWorker } from 'msw/browser'
// 2. 使用请求处理程序描述网络行为。
const worker = setupWorker(
http.get('https://github.com/octocat', ({ request, params, cookies }) => {
return HttpResponse.json(
{
message: '模拟响应',
},
{
status: 202,
statusText: '模拟状态',
},
)
}),
)
// 3. 通过启动Service Worker开始请求拦截。
await worker.start()
在您的应用程序中执行 GET https://github.com/octocat
请求将得到一个模拟响应,您可以在浏览器的"Network"选项卡中检查:
提示: 您知道吗,虽然Service Worker在单独的线程中运行,但您的模拟定义完全在客户端执行?这样,您可以使用相同的语言,如TypeScript、第三方库和内部逻辑来创建所需的模拟。
Node.js
工作原理
Node.js中没有Service Workers。相反,MSW实现了一个低级拦截算法,可以利用与浏览器相同的请求处理程序。这模糊了环境之间的界限,让您可以专注于网络行为。
有何不同?
- 不会stub
fetch
、axios
等。因此,您的测试对模拟一无所知; - 您可以在本地开发、调试以及测试中重用相同的请求处理程序。真正做到了跨所有环境和所有工具的网络行为单一真相来源。
使用示例
看看这个使用React Testing Library和Mock Service Worker的Vitest集成测试示例:
// test/Dashboard.test.js
import React from 'react'
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { render, screen, waitFor } from '@testing-library/react'
import Dashboard from '../src/components/Dashboard'
const server = setupServer(
// 使用请求处理程序描述网络行为。
// 提示:将处理程序移到它们自己的模块中,
// 并在浏览器和Node.js设置中导入它们!
http.get('/posts', ({ request, params, cookies }) => {
return HttpResponse.json([
{
id: 'f8dd058f-9006-4174-8d49-e3086bc39c21',
title: `测试时避免嵌套`,
},
{
id: '8ac96078-6434-4959-80ed-cc834e7fef61',
title: `我如何在2021年构建现代网站`,
},
])
}),
)
// 启用请求拦截。
beforeAll(() => server.listen())
// 重置处理程序,以便每个测试都可以修改它们
// 而不影响其他不相关的测试。
afterEach(() => server.resetHandlers())
// 不要忘记在之后清理。
afterAll(() => server.close())
it('显示最近帖子列表', async () => {
render(<Dashboard />)
// 🕗 等待帖子请求完成。
await waitFor(() => {
expect(
screen.getByLabelText('正在获取最新帖子...'),
).not.toBeInTheDocument()
})
// ✅ 断言正确的帖子已加载。
expect(
screen.getByRole('link', { name: /测试时避免嵌套/ }),
).toBeVisible()
expect(
screen.getByRole('link', { name: /我如何在2021年构建现代网站/ }),
).toBeVisible()
})
不要被淹没!我们准备了一步步的入门指南教程,您可以按照它学习如何将Mock Service Worker集成到您的项目中。
尽管API被称为setupServer
,但实际上并不涉及任何服务器!选择这个名称是为了让人熟悉,API的设计旨在模仿操作实际服务器。
赞助商
Mock Service Worker受到全球数十万工程师的信赖。它被Google、Microsoft、Spotify、Amazon等公司以及无数其他公司使用。尽管如此,这个库仍然是一个在业余时间维护的业余项目,没有机会在财务上支持哪怕一个全职贡献者。
您可以改变这一点! 考虑赞助这个围绕API模拟的最具创新方法之一的努力。与您的老板和同事讨论开源赞助的话题。让我们一起构建可持续的开源!
金牌赞助商
成为我们的金牌赞助商,您的信息将直接展示在这里,同时享受其他特权,如问题优先处理和与我们的个人咨询会议。
在我们的GitHub赞助商页面了解更多。
银牌赞助商
成为我们的银牌赞助商,您的个人资料图片和链接将在此处展示。
在我们的GitHub赞助商页面了解更多。