使用Vitest测试时react-i18next语言未设置报错
Vitest测试中react-i18n语言未加载导致抛出异常的解决方案
问题场景
项目依赖中包含如下校验语言的代码,当语言不是nb或en时会抛出错误:
function useI18N() { var _useTranslation = reactI18next.useTranslation(), t = _useTranslation.t, language = _useTranslation.i18n.language; if (language !== 'nb' && language !== 'en') { throw Error('Language must be either nb or en.'); } return t; } function withI18n(Component) { return function WrappedComponent(props) { var t = useI18N(); return React.createElement(Component, {...props, {i18n: t}}); }; }
测试时使用自定义的renderWithI18NContext方法注入i18n上下文,且i18n实例已完成初始化配置,但仅在Vitest测试时触发该错误,Vite构建或Jest测试均正常。
核心原因分析
- Vitest的模块隔离机制可能导致i18n初始化代码未在组件渲染前执行
i18n.changeLanguage是异步操作,组件渲染时语言切换未完成- Vitest的环境配置与Jest存在差异,导致react-i18next上下文未正确注入
解决步骤
1. 提前初始化i18n到测试流程
在测试入口文件(如setupTests.ts)中提前导入i18n实例,确保组件渲染前初始化完成:
// setupTests.ts import i18n from './path/to/your/i18n-config-file';
并在vitest.config.ts中配置该文件为测试前置脚本:
// vitest.config.ts export default defineConfig({ test: { setupFiles: './setupTests.ts', environment: 'jsdom', // 确保使用浏览器环境 }, });
2. 等待语言切换异步操作完成
i18n.changeLanguage返回Promise,修改renderWithI18NContext为异步函数,确保语言切换完成后再渲染组件:
export const renderWithI18NContext = async ( component: ReactNode, organisation?: Organisation, locale = 'nb' ) => { await i18n.changeLanguage(locale); // 等待语言切换完成 return render(componentWithI18NContext(component, organisation, locale)); };
对应测试用例也需改为异步:
it('should pass', async () => { await renderWithI18NContext( <ComponentTestContainer> component={<ComponentToTest {...props} />} </ComponentTestContainer> ); expect(…); });
3. 兜底方案:直接设置i18n语言
若上述方法无效,可在测试用例中直接跳过异步切换,手动设置i18n实例的语言:
it('should pass', () => { i18n.language = 'nb'; // 直接设置语言值 renderWithI18NContext( <ComponentTestContainer> component={<ComponentToTest {...props} />} </ComponentTestContainer> ); expect(…); });
内容的提问来源于stack exchange,提问作者phun-ky
相关产品推荐
相关产品推荐

