Cypress测试中如何正确mock window.foo.abc属性验证条件渲染功能
正确Mock Window属性的解决方案
原有写法失效原因
- 第一种
window:before:load监听写法失效:事件触发时被测页面的window.foo对象通常还未初始化,直接对win.foo.abc赋值会抛出未定义错误,导致赋值逻辑中断;如果事件监听注册晚于cy.visit()执行,也会错过事件触发时机导致赋值不生效。 - 第二种
cy.window()写法失效:代码中错误将页面window实例参数win写成了全局window,实际修改的是Cypress运行环境的window而非被测页面的window;另外如果cy.window()执行时页面业务代码已经完成了window.foo.abc的判断逻辑,后续修改也不会生效。
推荐实现方案
方案1:页面加载前预注入(适配绝大多数场景)
如果业务代码在页面初始化阶段就会读取window.foo.abc做判断,必须在页面加载前就完成赋值,写法如下:
// 测试window.foo.abc为true的场景 it('abc为true时对应内容正常展示', () => { // 监听必须放在cy.visit之前注册 Cypress.once('window:before:load', (win) => { // 提前初始化父级对象,避免未定义报错 win.foo = win.foo || {} win.foo.abc = true }) cy.visit('/你的页面路由') // 补充对应的断言逻辑 cy.get('[data-testid=target-content]').should('be.visible') }) // 测试window.foo.abc为false的场景 it('abc为false时对应内容隐藏', () => { Cypress.once('window:before:load', (win) => { win.foo = win.foo || {} win.foo.abc = false }) cy.visit('/你的页面路由') cy.get('[data-testid=target-content]').should('not.exist') })
注意使用
Cypress.once注册单次监听,避免事件被重复触发影响其他用例的mock状态。
方案2:页面加载后动态修改(适配交互后才读取值的场景)
如果业务逻辑是在用户点击、输入等交互操作后才会读取window.foo.abc,可以在交互前完成赋值:
cy.visit('/你的页面路由') // 交互前修改window属性 cy.window().then(win => { win.foo = win.foo || {} win.foo.abc = true }) // 触发读取该值的交互逻辑 cy.get('[data-testid=trigger-btn]').click() // 断言逻辑 cy.get('[data-testid=target-content]').should('be.visible')
内容的提问来源于stack exchange,提问作者Dvir
相关产品推荐
相关产品推荐

