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

Cypress 10 E2E测试中方法Stub失效问题求助

Cypress E2E测试Stub类实例方法无效的原因及解决办法

核心原因

E2E测试和组件测试的运行环境完全不同:

  • 组件测试是在Node环境中直接渲染组件,测试代码和组件代码共享同一个运行上下文,你导入的userUtil实例和组件使用的是同一个,所以Stub能生效。
  • E2E测试中,测试代码运行在Node端,而应用代码运行在浏览器端,两者是完全隔离的两个环境。你在测试代码里导入并Stub的userUtil,和浏览器里应用实际调用的userUtil是两个完全独立的实例,自然不会影响到应用的执行逻辑。

解决办法

方法1:将实例挂载到浏览器全局对象,在浏览器环境中Stub

首先在应用代码的userUtil.ts中,仅在测试环境下把实例挂载到window:

export class UserUtil {
    public async init() {
        // ...原逻辑
    }
}

const userUtil = new UserUtil();
export default userUtil;

// 仅测试环境暴露到全局
if (process.env.NODE_ENV === 'test') {
    (window as any).userUtil = userUtil;
}

然后在测试代码中,先访问页面(确保应用代码加载完成),再通过cy.window()获取浏览器环境中的实例并Stub:

beforeEach(() => {
  cy.visit('/');
  cy.window().then((win) => {
    // 对浏览器环境中的userUtil实例进行Stub
    cy.stub(win.userUtil, 'init').as('init');
  });
});

方法2:提供依赖注入入口,替换实例

如果不想直接暴露全局变量,可以在应用代码中添加一个实例替换方法:

export class UserUtil {
    public async init() {
        // ...原逻辑
    }
}

let userUtilInstance = new UserUtil();

// 提供替换实例的方法
export const setUserUtilInstance = (instance: UserUtil) => {
    userUtilInstance = instance;
};

export default userUtilInstance;

测试代码中,通过浏览器环境调用替换方法,传入Stub后的实例:

beforeEach(() => {
  cy.visit('/');
  cy.window().then((win) => {
    // 创建一个新的UserUtil实例并Stub其init方法
    const stubbedInstance = new win.UserUtil();
    cy.stub(stubbedInstance, 'init').as('init');
    // 替换应用中的实例
    win.setUserUtilInstance(stubbedInstance);
  });
});

注意事项

  • E2E测试中所有对应用代码的修改,都必须通过cy.window()进入浏览器环境操作,不能直接在测试代码中修改应用的变量或实例。
  • 全局变量的暴露要限制在测试环境,避免生产环境泄露不必要的代码。

内容的提问来源于stack exchange,提问作者Rachel Fishbein

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:45:31