如何在Cypress中两次Stub同一API端点以返回不同响应?
在Cypress中为同一API端点设置两次不同Stub响应的正确方法
你遇到的问题核心在于:Cypress会优先使用最后定义的同类型路由,所以一开始同时定义两个POST access-tokens路由时,第一次请求也会匹配到最后那个成功响应的路由,导致不符合预期。另外,你尝试在onResponse回调里调用cy.route的方式不可行,因为Cypress命令必须在它的命令执行队列中运行,普通回调函数里的命令不会被正确处理。
下面给你两种可行的解决方案,分别基于旧版的cy.route和新版推荐的cy.intercept(后者更灵活,推荐使用):
方案一:使用cy.route,在第一次请求完成后重新定义路由
这个思路是先定义失败路由,触发第一次登录并等待请求完成,然后再覆盖路由为成功响应,最后进行第二次登录:
// 1. 先定义失败的路由 cy.route('POST', 'access-tokens', '@loginFailResponse', { status: 401 }).as('loginFail') // 输入错误凭证并提交(触发第一次请求) cy.get("form input[type='email']").type("bad@email.com") cy.get("form input[type='password']").type("Bad password") cy.get("form").submit() // 等待第一次请求完成,确认失败后重新定义路由 cy.wait('@loginFail').then(() => { // 2. 覆盖为成功响应的路由 cy.route('POST', 'access-tokens', '@loginSuccessResponse').as('loginSuccess') }) // 输入正确凭证并提交(触发第二次请求) cy.get("form input[type='password']").clear().type("g00d@password.com") cy.get("form").submit() // 验证成功请求完成 cy.wait('@loginSuccess')
方案二:使用新版cy.intercept(推荐)
cy.intercept是Cypress官方推荐替代cy.route的命令,它支持动态判断请求并返回不同响应,不需要反复定义路由:
// 初始化请求计数器 let loginRequestCount = 0; // 拦截POST请求,根据请求次数返回不同响应 cy.intercept('POST', 'access-tokens', (req) => { loginRequestCount++; if (loginRequestCount === 1) { // 第一次请求返回401失败响应 req.reply({ statusCode: 401, fixture: 'login_screen/login_fail_response.json' // 替换为你的失败fixture路径 }); } else { // 第二次及以后请求返回成功响应 req.reply({ fixture: 'login_screen/login_success_response.json' // 替换为你的成功fixture路径 }); } }).as('loginRequest'); // 第一次登录(错误凭证) cy.get("form input[type='email']").type("bad@email.com") cy.get("form input[type='password']").type("Bad password") cy.get("form").submit() cy.wait('@loginRequest') // 等待第一次请求完成 // 第二次登录(正确凭证) cy.get("form input[type='password']").clear().type("g00d@password.com") cy.get("form").submit() cy.wait('@loginRequest') // 等待第二次请求完成
为什么你之前的方法无效?
- 同时定义两个同路由的
cy.route时,Cypress会采用最后定义的那个,所以第一次请求也会返回成功响应,不符合你的预期。 - 在
onResponse回调里调用cy.route的方式错误:Cypress命令必须通过链式调用(比如.then())加入到它的执行队列中,普通回调函数里的命令不会被Cypress正确处理,这就是你遇到“不允许在Promise中调用cy命令”问题的原因。
内容的提问来源于stack exchange,提问作者Filip Bartuzi
相关产品推荐
相关产品推荐

