如何使用MSW条件模拟错误响应测试4xx/5xx状态下的UI
基于MSW实现灵活的多状态响应测试方案
不需要每次手动修改handler的返回状态码,只需要在现有逻辑上做少量改动,就能灵活触发2xx、4xx、5xx各类响应,既不影响日常开发的正常请求逻辑,也能全覆盖错误态的UI测试场景。
方案1:测试用例内临时覆盖handler(适合自动化测试场景)
如果是在Jest、Vitest这类测试框架里跑用例,完全不需要改动公共的handler配置文件。MSW本身提供了server.use方法,可以在单个测试用例执行期间临时替换接口处理逻辑,用例跑完后会自动重置回默认的成功响应配置,不会造成测试用例之间的状态污染。
举个实际的测试写法例子:
// 测试404错误态UI test('接口返回404时,正确展示资源不存在提示', async () => { // 临时替换/items/接口的处理逻辑,固定返回404响应 server.use( rest.get('/items/', (_req, res, ctx) => { return res( ctx.status(404), ctx.json({ message: '你要找的商品不存在' }) ); }) ); // 挂载组件,等待接口请求渲染完成,断言页面展示内容 render(<ItemsPage />); await screen.findByText('你要找的商品不存在,请返回重新浏览'); }); // 测试500错误态UI test('接口返回500时,正确展示服务器异常提示', async () => { server.use( rest.get('/items/', (_req, res, ctx) => { return res( ctx.status(500), ctx.json({ message: '服务器开小差了' }) ); }) ); render(<ItemsPage />); await screen.findByText('服务暂时不可用,请稍后再试'); });
这种方式灵活性最高,每个测试用例可以自定义任意状态码、响应体内容、甚至响应延迟,完全不需要侵入公共的mock代码,是测试场景下的最优选择。
方案2:给handler加内置的状态触发逻辑(适合手动调试场景)
如果是日常开发时需要在浏览器里手动切换不同响应状态调试UI,可以给现有handler加上简单的判断逻辑,通过自定义请求头、URL查询参数来触发对应的错误响应,日常不带特殊参数的请求依然走原来的200成功逻辑,完全不影响正常开发。
举个改造后的handler例子:
import { rest } from 'msw'; import { items } from './apiValues'; // 提前预置常用的错误响应模板,减少重复代码 const commonErrorPayload = { 403: { message: '没有权限访问该内容' }, 404: { message: '请求的资源不存在' }, 500: { message: '服务器内部错误' }, 502: { message: '网关请求失败' } }; export const handlers = [ rest.get('/items/', (req, res, ctx) => { // 优先读取请求头里的自定义状态标识,也可以换成读取URL查询参数 const mockStatus = req.headers.get('x-mock-trigger-status') || req.url.searchParams.get('mock_status'); // 如果检测到了需要模拟的状态码,就返回对应的错误响应 if (mockStatus) { const statusCode = Number(mockStatus); return res( ctx.status(statusCode), ctx.json(commonErrorPayload[statusCode] || { message: '模拟错误响应' }) ); } // 默认逻辑不变,返回200的成功数据 return res(ctx.status(200), ctx.json(items)); }), ];
改造完成后,不管是在浏览器地址栏把请求路径改成/items/?mock_status=500,还是在代码发请求时带上x-mock-trigger-status: 403的请求头,都能直接触发对应的错误响应,不需要再手动改handler的状态码。
选型参考
- 写自动化测试时优先用临时覆盖handler的方式,和公共mock代码完全隔离,避免误改提交
- 日常手动调试UI时可以加上参数触发逻辑,做到一键切换不同响应状态
- 两种方式结合使用,就能覆盖所有测试、调试场景,完全省去来回改handler的繁琐操作
内容的提问来源于stack exchange,提问作者Timothy Oliver
相关产品推荐
相关产品推荐

