使用Angular与Cypress测试路径部分相同的HTTP路由问题
问题根因
你遇到的拦截失效问题核心是Cypress cy.intercept 默认使用前缀匹配规则,且拦截器按定义顺序优先匹配:先定义的cars/拦截规则会匹配所有路径前缀为cars/的请求,包括cars/details,因此后者的拦截器永远不会被触发。
你尝试的Window上stub Angular的方案本身存在限制:只有Angular开发环境构建的产物才会把ng对象挂载到Window上,生产环境构建会移除该对象,自然会报ng is not defined错误,该方案适用场景极窄,无需优先尝试。
可行解决方案
方案1:调整拦截顺序+使用严格匹配规则(优先推荐)
无需修改业务代码,仅调整测试用例的拦截配置即可解决:
- 拦截器定义顺序遵循「越具体的路径越靠前」原则,把
cars/details的拦截逻辑放在cars/的拦截逻辑之前定义 - 对路径要求严格匹配的场景,使用正则/精确匹配规则替代默认前缀匹配,避免宽范围拦截覆盖子路径请求:
// 先定义更具体的 cars/details 拦截 cy.intercept('GET', /^\/cars\/details$/, { statusCode: 200, body: { /* 自定义的详情接口返回值 */ } }).as('getCarDetails') // 再定义通用的 cars/ 拦截,用正则匹配精确的 /cars/ 路径,避免匹配子路径 cy.intercept('GET', /^\/cars\/$/, { statusCode: 200, body: { /* 自定义的列表接口返回值 */ } }).as('getCarsList')
方案2:给通用拦截增加命中次数限制
如果你的测试逻辑中cars/请求只会触发固定次数,可以给第一个拦截加times参数,命中指定次数后自动失效,后续请求就会走到下一个匹配的拦截器:
// cars/ 拦截仅生效1次,命中后自动失效 cy.intercept('GET', '/cars/', { times: 1 }, { statusCode: 200, body: { /* 自定义的列表接口返回值 */ } }).as('getCarsList') // 后续的 cars/details 请求会正常匹配当前拦截规则 cy.intercept('GET', '/cars/details', { statusCode: 200, body: { /* 自定义的详情接口返回值 */ } }).as('getCarDetails')
内容的提问来源于stack exchange,提问作者MVCWannaB
相关产品推荐
相关产品推荐

