Cypress单元测试React组件报错:useNavigate()仅可在<Router>组件上下文使用
问题根因
你遇到的两个报错都是Cypress组件测试和E2E测试的上下文差异导致的:
- Cypress组件测试的组件运行在独立的iframe沙箱中,和Cypress全局命令的运行上下文完全隔离,你在
cy.login()中写入全局localStorage的token,组件运行的沙箱根本读不到,就算手动传了对的token,只要没写到对应的沙箱上下文里,请求就会401 - mount显示<Unknown.../>是因为Cypress组件测试的转译配置没有对齐你当前项目的React编译规则,组件没有被正确解析
解决步骤
- 修复token不生效问题
不要在before钩子中调用全局cy.login(),在每次mount组件前直接往组件运行的上下文写入token即可,修改测试代码如下:
import * as React from 'react'; import { mount } from '@cypress/react'; import User from './index'; describe('User component', ()=>{ it('Mount user', () => { // 写入当前组件沙箱的localStorage,替换成你项目实际的token字段和有效值 window.localStorage.setItem('access_token', '你的有效token值') mount(<User />); }); })
如果需要复用登录逻辑,可以自定义封装带登录逻辑的mount命令,每次调用时自动注入token。
- 修复组件显示Unknown问题
修改你的cypress.config.js配置,对齐项目的编译规则,以下分别是webpack和vite项目的示例配置:
webpack项目配置示例
const { defineConfig } = require('cypress') // 引入你项目本地的webpack配置 const webpackConfig = require('./webpack.config.js') module.exports = defineConfig({ component: { devServer: { framework: 'react', bundler: 'webpack', webpackConfig, }, }, })
vite项目配置示例
const { defineConfig } = require('cypress') // 引入你项目本地的vite配置 const viteConfig = require('./vite.config.js') module.exports = defineConfig({ component: { devServer: { framework: 'react', bundler: 'vite', viteConfig, }, }, })
- (可选)优化组件测试逻辑
组件测试不需要真实调用后端接口,你可以直接用cy.interceptmock组件的API请求,完全避开token校验问题,代码示例:
it('Mount user', () => { cy.intercept('GET', '/api/user/info', { statusCode: 200, body: { // 替换成接口实际返回的mock数据结构 id: 1, name: '测试用户' } }).as('getUserInfo') mount(<User />); cy.wait('@getUserInfo') });
内容的提问来源于stack exchange,提问作者CodeWorld
相关产品推荐
相关产品推荐

