Cypress测试中Axios请求轮询失效问题求助
Axios轮询功能未执行的修复方案(Cypress环境)
我在Cypress中开发的Axios请求轮询功能未实际执行轮询操作,需要修复方案,仅允许使用Axios实现。
相关代码
subscriptionChange.spec.js
helperFunctions .checkSubscriptionId(apiEndpointUrl, tokenDetails) .then((subscriptionId) => { console.log("Sub id data::" + subscriptionId); if (subscriptionId != null) { cy.request({ method: "POST", url: apiEndpointUrl + `/someurl/v1/subscription/${subscriptionId}/change`, headers: { Authorization: "Bearer " + tokenDetails, }, body: { userId: userId, planCode: "plus_annual", }, }).then((resp) => { console.log("Change Subscription response ::" + resp); const planName = resp.body.subscriptionChange.plan.name; const planCode = resp.body.subscriptionChange.plan.code; expect(resp.status).to.eq(200); expect(planCode).to.contain("plus_annual"); expect(planName).to.contain("Plus Annual"); }); } });
helperFunctions.js
class helperFunctions { checkSubscriptionId = async (apiEndpointUrl, tokenDetails, retryNo = 0) => { const options = { headers: { Authorization: "Bearer " + tokenDetails, }, }; return await axios .get(apiEndpointUrl + "/someurl/v1/user/info", options) .then((res) => { console.log("RESPONSE ==== : ", res); const subscriptionId = res.data.user.subscription.gateway_subscription_id; if (retryNo >= NUM_RETRIES) { throw new Error( `Subscription not found after ${NUM_RETRIES} retries` ); } // If it is found, return if (subscriptionId || retryNo >= NUM_RETRIES) { return; } return new Cypress.Promise((resolve) => { setTimeout(() => { console.log("Retrying ::" + retryNo); resolve( this.checkSubscriptionId(apiEndpointUrl, tokenDetails, retryNo + 1) ); }, 2000); }); }) .catch((err) => { console.log("ERROR: ====", err); }); }; }
问题分析
- 逻辑判断错误:
if (subscriptionId || retryNo >= NUM_RETRIES)中,当subscriptionId不存在且未达到重试上限时,会直接return(返回undefined),不会触发后续的重试逻辑。同时该条件中的retryNo >= NUM_RETRIES已经在上一步判断过,属于冗余判断。 - 未返回有效数据:找到
subscriptionId时没有返回该值,导致上层then中拿到的subscriptionId为undefined,无法执行后续的订阅变更请求。 - 错误被吞掉:
catch块仅打印错误但未重新抛出,导致轮询失败时上层无法感知到错误。
修复后的代码(helperFunctions.js)
class helperFunctions { checkSubscriptionId = async (apiEndpointUrl, tokenDetails, retryNo = 0) => { const options = { headers: { Authorization: "Bearer " + tokenDetails, }, }; try { const res = await axios.get(apiEndpointUrl + "/someurl/v1/user/info", options); console.log("RESPONSE ==== : ", res); const subscriptionId = res.data.user.subscription.gateway_subscription_id; // 达到重试上限仍未找到,抛出错误 if (retryNo >= NUM_RETRIES) { throw new Error(`Subscription not found after ${NUM_RETRIES} retries`); } // 找到subscriptionId,直接返回 if (subscriptionId) { return subscriptionId; } // 未找到,延迟后重试 console.log("Retrying ::" + retryNo); await new Promise(resolve => setTimeout(resolve, 2000)); return this.checkSubscriptionId(apiEndpointUrl, tokenDetails, retryNo + 1); } catch (err) { console.log("ERROR: ====", err); // 重新抛出错误,让上层捕获 throw err; } }; }
修复说明
- 改用
try/catch替代Promise链式调用,逻辑更清晰,避免回调嵌套。 - 修正判断顺序:先检查重试上限,再判断是否找到
subscriptionId,找不到则触发重试。 - 找到
subscriptionId时明确返回该值,确保上层能拿到有效数据。 - 使用原生
Promise配合setTimeout实现延迟,替代Cypress.Promise(效果一致但更通用)。 catch块重新抛出错误,保证错误能传递到上层测试逻辑中。
内容的提问来源于stack exchange,提问作者soccerway
相关产品推荐
相关产品推荐

