如何在Jest+jsdom环境下用MSW对React应用做单元测试?
解决MSW 2.x + Jest 2.x(jsdom环境)的服务端模拟问题
核心问题原因
MSW 2.0 重构了模块结构,移除了msw/node和msw/browser的单独入口,统一从msw包导出setupServer和setupWorker。你遇到的找不到msw/node模块的问题,就是因为沿用了MSW 1.x的导入方式。同时,Jest的jsdom环境属于模拟浏览器的Node运行环境,必须使用setupServer而非setupWorker。
分步解决办法
1. 修正MSW导入语句
将原来的:
import { setupServer } from 'msw/node'
改为:
import { setupServer } from 'msw'
2. 确保Jest使用jsdom环境
在项目的jest.config.js(或jest.config.ts)中明确配置测试环境:
module.exports = { testEnvironment: 'jsdom', // 其他Jest配置项... }
如果仅需在特定测试文件启用jsdom,可在文件顶部添加注释:
/** @jest-environment jsdom */
3. 配置并使用MSW Server
创建MSW服务器实例,在测试生命周期中管理其启动/关闭:
import { render, screen } from '@testing-library/react' import { setupServer } from 'msw' import { rest } from 'msw' import YourComponent from './YourComponent' // 定义请求处理逻辑 const server = setupServer( rest.get('/api/data', (req, res, ctx) => { return res(ctx.json({ message: 'Mocked response' })) }) ) // 测试前启动服务器 beforeAll(() => server.listen()) // 每个测试后重置请求处理(避免测试间污染) afterEach(() => server.resetHandlers()) // 测试结束后关闭服务器 afterAll(() => server.close()) test('renders data from mocked API', async () => { render(<YourComponent />) const dataElement = await screen.findByText('Mocked response') expect(dataElement).toBeInTheDocument() })
4. 适配jsdom的Fetch支持(可选)
Jest 29.x搭配的jsdom版本默认已支持fetch,但如果遇到fetch is not defined错误,可安装whatwg-fetch并在Jest的全局setup文件中导入:
npm install whatwg-fetch --save-dev
在setupTests.js中添加:
import 'whatwg-fetch'
关键注意点
setupWorker仅用于真实浏览器环境(如Cypress、浏览器端E2E测试),Jest的jsdom环境本质是Node运行时,必须用setupServer。- MSW 2.x无需额外配置
msw/node的polyfill,框架会自动适配Node/jsdom环境。
内容的提问来源于stack exchange,提问作者Brann
相关产品推荐
相关产品推荐

