You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保cy.writeFile()在cy.intercept()执行前完成?

解决Cypress中fixture更新后再执行cy.intercept的问题

你的问题核心是cy.intercept使用{fixture: 路径}配置时,会在调用intercept的瞬间就读取文件内容,而非实际请求触发时再读取。所以即便后续通过cy.writeFile更新了文件,拦截逻辑已经提前使用了旧的fixture内容。

下面给出两种可靠的解决方案:

方案一:直接使用内存中的更新后数据(推荐)

跳过文件写入/读取的异步依赖,直接将更新后的内存数据作为intercept响应体,彻底避免文件系统的时序问题:

describe('NBA pregame EventTile verification', () => {

  beforeEach('Enforce game start time', function () {

    // 修改updateSchedule,返回更新后的数据集
    const updateSchedule = (filePath, updateCallback) => {
      return cy.fixture(filePath).then((nbaData) => {
        updateCallback(nbaData);
        // 可选:写入文件保留修改 + 返回内存中的更新后数据
        return cy.writeFile(filePath, nbaData).then(() => nbaData);
      });
    };

    // Update QB schedule and set up interception
    const updateQBAndIntercept = () => {
      return updateSchedule('Odds/QB/NBA1Schedule.json', (nbaData) => {
        const nbaGame = nbaData.NBA[0];
        const currentTimestamp = Date.now();
        const adjustedStartTime = currentTimestamp + (2 * 60 * 60 * 1000); // 2小时后
        nbaGame.startTime = adjustedStartTime;
      }).then((updatedQBData) => {
        // 直接用内存数据作为响应,不再读取文件
        return cy.intercept('GET', '**/quarterback/lighterGames/leagues/**', updatedQBData).as('nbaPregameqb');
      });
    };

    // Update DK schedule and set up interception
    const updateDKAndIntercept = () => {
      return updateSchedule('Odds/DK/NBA1Schedule.json', (nbaData) => {
        const nbaGame = nbaData.NBA[0];
        const currentDate = new Date();
        const adjustedStartDate = new Date(currentDate.getTime() + (2 * 60 * 60 * 1000)); // 2小时后
        nbaGame.startDate = adjustedStartDate.toISOString();
      }).then((updatedDKData) => {
        return cy.intercept('GET', '**/sports-oddsapp-offers.xreapps.net/dk/events/**', updatedDKData).as('nbaPregamedk');
      });
    };

    // 无需动态更新的intercept保持原配置
    cy.intercept('GET', '**/quarterback/lighterGame/league/**', {
      fixture: 'Odds/QB/NBA1Details.json'
    }).as('nbaPregameDetailqb');

    cy.intercept('GET', '**/sports-oddsapp-offers.xreapps.net/dk/props,lines/**', {
      fixture: 'Odds/DK/NBA1Details.json'
    }).as('nbaPregameDetaildk');

    const launchAppAndWaitForIntercepts = () => {
      cy.launchOddsApp();
      return cy.wait(['@nbaPregameqb', '@nbaPregamedk']);
    };

    // 链式调用保持不变
    updateQBAndIntercept()
      .then(updateDKAndIntercept)
      .then(launchAppAndWaitForIntercepts);
  })

  context('Odds Explorer Page', () => {

    it.only('Should have NBA pregame Tile', () => {
      // 你的测试逻辑
    })
  })
})

方案二:在intercept中动态读取最新文件(需依赖文件场景)

如果必须通过修改后的fixture文件响应请求,可在intercept的handler函数中用cy.readFile读取最新内容,确保请求触发时拿到的是更新后的数据:

// 修改updateQBAndIntercept逻辑示例
const updateQBAndIntercept = () => {
  // 先完成文件更新
  return updateSchedule('Odds/QB/NBA1Schedule.json', (nbaData) => {
    const nbaGame = nbaData.NBA[0];
    const currentTimestamp = Date.now();
    const adjustedStartTime = currentTimestamp + (2 * 60 * 60 * 1000);
    nbaGame.startTime = adjustedStartTime;
  }).then(() => {
    // 请求触发时读取最新文件
    return cy.intercept('GET', '**/quarterback/lighterGames/leagues/**', (req) => {
      return cy.readFile('cypress/fixtures/Odds/QB/NBA1Schedule.json').then(data => {
        req.reply(data);
      });
    }).as('nbaPregameqb');
  });
};

注意:这里需要填写完整的fixture文件相对路径(相对于项目根目录),避免路径解析错误。

两种方案对比:

  • 方案一性能更优,无额外文件IO操作,时序完全可控;
  • 方案二适合需要保留修改后fixture文件,供后续测试复用的场景。

内容的提问来源于stack exchange,提问作者Kakali Mahapatra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 10:34:51