Cypress组件测试:如何在Vite React应用中Mock ES6模块?
解决Cypress组件测试中Stub ES6自定义Hook的问题
针对你在Vite+React项目中遇到的「无法Stub ES6导入模块」错误,以下是几种可行的解决方案:
方案1:Stub整个模块的导出对象
ES6模块的静态导入特性导致cy.stub()无法直接修改单个导入项,你可以先导入整个模块对象,再Stub对应的Hook:
// 导入整个模块 import * as AuthHooks from '../../src/hooks/useKeycloakAuth' describe('目标组件测试', () => { it('Mock用户已登录状态', () => { // Stub模块中的自定义Hook,返回模拟状态 cy.stub(AuthHooks, 'useKeycloakAuth').returns({ isLoggedIn: true, user: { username: 'test_user', email: 'test@example.com' } }) // 挂载组件 cy.mount(<YourTargetComponent />) // 验证组件行为 cy.contains('欢迎回来,test_user').should('be.visible') }) it('Mock用户未登录状态', () => { cy.stub(AuthHooks, 'useKeycloakAuth').returns({ isLoggedIn: false, user: null }) cy.mount(<YourTargetComponent />) cy.contains('请登录').should('be.visible') }) })
方案2:通过React Context绕过模块Stub
如果你的自定义Hook依赖React Context提供Keycloak状态,直接在测试中替换Context Provider的value会更稳定,避免模块Stub的兼容性问题:
import { KeycloakAuthContext } from '../../src/contexts/KeycloakContext' describe('目标组件测试', () => { it('模拟已登录状态', () => { const mockAuthContext = { isLoggedIn: true, user: { username: 'test_user' }, login: cy.stub().as('loginFn') // 还可以Stub Context中的方法 } // 用Mock的Context包裹组件 cy.mount( <KeycloakAuthContext.Provider value={mockAuthContext}> <YourTargetComponent /> </KeycloakAuthContext.Provider> ) cy.contains('test_user').should('be.visible') cy.get('button[data-testid="login-btn"]').click() cy.get('@loginFn').should('have.been.called') }) })
方案3:清除模块缓存避免Stub残留
如果多次测试间Stub状态出现污染,可在beforeEach中清除模块缓存(针对CommonJS,ESM可结合Vite的热重载配置):
beforeEach(() => { // 清除CommonJS模块缓存 delete require.cache[require.resolve('../../src/hooks/useKeycloakAuth')] })
额外配置检查
确保你的cypress.config.js中Vite配置与项目一致,比如别名解析:
// cypress.config.js export default defineConfig({ component: { devServer: { framework: 'react', bundler: 'vite', viteConfig: { resolve: { alias: { '@': './src' // 匹配项目中的别名配置 } } } } } })
内容的提问来源于stack exchange,提问作者Ekansh
相关产品推荐
相关产品推荐

