Cypress测试Next.js SSR应用时如何拦截Axios发送的RESTful API请求
问题核心原因
cy.intercept() 只能拦截经过Cypress控制的浏览器实例发出的请求,Next.js SSR阶段的请求是Node.js服务端直接向外发起的,没有走浏览器代理链路,所以无法被直接拦截。以下是可落地的解决方案:
可选解决方案
方案1:业务代码侧加环境判断拦截
- 测试环境启动Next.js服务时传入特殊标识的环境变量,比如
NEXT_PUBLIC_ENABLE_TEST_MOCK=true - 在Axios的全局请求拦截器中加判断,当识别到测试环境标识时,匹配对应请求路径直接返回本地fixture数据,跳过真实请求:
import axios from 'axios'; // 直接引入Cypress的fixture文件复用数据 import userListFixture from '../cypress/fixtures/user-list.json'; import orderDetailFixture from '../cypress/fixtures/order-detail.json'; const mockRuleMap = { 'GET:/api/users': userListFixture, 'GET:/api/order/*': orderDetailFixture }; if (process.env.NEXT_PUBLIC_ENABLE_TEST_MOCK === 'true') { axios.interceptors.request.use((config) => { const ruleKey = `${config.method.toUpperCase()}:${config.url}`; if (mockRuleMap[ruleKey]) { // 抛出标记过的自定义错误,在响应拦截器里处理成正常返回 return Promise.reject({ __mocked__: true, data: mockRuleMap[ruleKey] }); } return config; }); axios.interceptors.response.use( (res) => res, (error) => { if (error.__mocked__) { return Promise.resolve({ data: error.data, status: 200 }); } return Promise.reject(error); } ); }
- 该方案不需要引入额外依赖,改动量小,mock数据直接复用已有的Cypress fixture即可。
方案2:使用MSW(Mock Service Worker)统一拦截
- MSW支持同时拦截Node.js服务端和浏览器端发起的请求,完美适配Next.js SSR场景,和Cypress的生态兼容度高。
- 只需要编写一套mock规则,就可以同时覆盖SSR阶段和客户端hydrate之后的所有请求,不需要分别处理两端逻辑,也不会侵入业务代码的核心逻辑。
- 测试时只需要在Next.js服务启动时加载MSW的Node端中间件,Cypress运行时自动激活浏览器端的MSW拦截即可。
方案3:全局代理转发到本地mock服务
- 如果不想改动任何业务代码,可以在启动Next.js测试服务时配置全局HTTP代理,把所有对外的RESTful API请求转发到本地启动的mock服务上,mock服务根据请求路径返回对应fixture数据。
- 可以用任何你熟悉的工具搭建本地mock服务,只需要保证返回的格式和真实接口一致即可。
内容的提问来源于stack exchange,提问作者maaz
相关产品推荐
相关产品推荐

