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

从CRA迁移到Vite后,Vitest测试中Emotion css props无法获取theme对象

解决Vitest测试中Emotion Theme为空对象的问题

核心原因

测试环境未通过ThemeProvider注入主题上下文,而运行时应用的根组件通常会包裹ThemeProvider,导致测试时组件无法获取主题数据。此外需确认Vitest是否正确应用了Emotion的Babel转换配置。

解决方案

1. 在测试全局配置中添加ThemeProvider包裹

修改src/setupTests.ts,将所有测试组件自动包裹在Emotion的ThemeProvider中,确保主题上下文可用:

import { ThemeProvider } from '@emotion/react';
import { render } from '@testing-library/react';
import { theme } from './path/to/your/theme'; // 替换为项目实际主题文件路径

// 重写render方法,默认注入主题
export const render = (ui: React.ReactElement, options?: Parameters<typeof render>[1]) => {
  return render(<ThemeProvider theme={theme}>{ui}</ThemeProvider>, options);
};

之后在测试文件中使用这个自定义render方法渲染组件,即可获取完整主题对象。

2. 确认Vitest正确应用Emotion的Babel插件

虽然Vite配置中已添加@emotion/babel-plugin,需确保Vitest在测试模式下加载该配置。可在Vitest配置中显式指定Babel选项:
修改vite.config.ts的test字段:

test: {
  globals: true,
  environment: 'happy-dom',
  setupFiles: './src/setupTests.ts',
  // 显式配置Babel插件
  babel: {
    plugins: ['@emotion/babel-plugin'],
  },
}

若使用React 17+,也可通过jsxImportSource配置Emotion,无需依赖Babel插件:
在tsconfig.json中添加:

{
  "compilerOptions": {
    "jsxImportSource": "@emotion/react"
  }
}

同时调整Vite React插件配置:

react({
  jsxImportSource: '@emotion/react',
})

3. 手动包裹测试组件(局部方案)

若未使用全局自定义render方法,可在单个测试中手动包裹主题上下文:

import { ThemeProvider } from '@emotion/react';
import { render } from '@testing-library/react';
import SomeComponent from './Component';
import { theme } from './path/to/your/theme';

test('渲染组件并正确获取主题', () => {
  render(
    <ThemeProvider theme={theme}>
      <SomeComponent />
    </ThemeProvider>
  );
  // ... 断言逻辑
});

总结

最常见的原因是测试环境缺少主题上下文注入,通过全局或局部添加ThemeProvider即可解决。同时需确保Emotion的编译配置在测试环境中正常生效,避免因转换不完整导致主题无法传递。

内容的提问来源于stack exchange,提问作者Dimitris Karagiannis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 03:44:53