如何在Mock Service Worker和React Testing Library中获取请求body内容
解决方案
你原有代码的核心问题是将ctx.status(401)单独声明,没有传入res方法的参数列表中,导致状态码配置不生效。根据你使用的MSW版本,对应调整方式如下:
MSW 1.x 版本写法
1.x版本会自动解析请求体,直接从req.body中取对应字段即可:
const server = setupServer( rest.post("https://testlogin.com/api/v1/login", (req, res, ctx) => { if (req.body.email !== "test@example.com") { // 所有响应配置都要作为res的参数传入 return res( ctx.status(401), ctx.json({ success: false, message: "邮箱或密码错误" }) ) } // 邮箱匹配时的成功返回逻辑 return res( ctx.json({ success: true, token: "fake-test-token" }) ) }) );
MSW 2.x 版本写法
2.x版本需要手动异步解析请求体,回调函数要标记为async:
const server = setupServer( rest.post("https://testlogin.com/api/v1/login", async (req, res, ctx) => { // 解析JSON格式请求体,form-data格式可替换为 await req.formData() const body = await req.json() if (body.email !== "test@example.com") { return res( ctx.status(401), ctx.json({ success: false, message: "邮箱或密码错误" }) ) } return res( ctx.json({ success: true, token: "fake-test-token" }) ) }) );
如果使用form-data提交请求,解析后通过formData.get('email')获取对应字段即可。
更优实现方案
- 抽离校验逻辑为独立函数,方便复用和后续调整规则:
// 独立校验逻辑,后续修改校验规则只需改这一处 const isLegalLoginEmail = (email) => email === "test@example.com" const server = setupServer( rest.post("https://testlogin.com/api/v1/login", async (req, res, ctx) => { const body = await req.json() if (!isLegalLoginEmail(body.email)) { return res(ctx.status(401), ctx.json({ success: false, message: "邮箱不匹配" })) } return res(ctx.json({ success: true, token: "fake-test-token" })) }) )
- 把测试用的固定账号、响应字段值抽到单独的常量配置文件中,避免硬编码散落在多个mock文件中
- 单测中需要覆盖特殊异常场景时,可动态临时修改mock规则,不需要改动全局server配置:
test("账号封禁场景登录提示正确", () => { // 临时覆盖当前测试用例的登录接口返回 server.use( rest.post("https://testlogin.com/api/v1/login", async (req, res, ctx) => { return res(ctx.status(403), ctx.json({ success: false, message: "账号已被封禁" })) }) ) // 执行对应测试逻辑 })
内容的提问来源于stack exchange,提问作者Patrick Obafemi
相关产品推荐
相关产品推荐

