如何正确Mock i18next-http-backend,避免触发HTTP请求?
如何Mock i18next以阻止HTTP后端请求?
问题场景
我在React应用中按如下方式配置了i18next-http-backend:
import i18n from 'i18next' import Backend from 'i18next-http-backend' import detector from 'i18next-browser-languagedetector' import { initReactI18next } from 'react-i18next' i18n .use(Backend) .use(detector) .use(initReactI18next) .init({ backend: { loadPath: `${process.env.PUBLIC_URL || ''}/locales/{{lng}}/{{ns}}.json`, addPath: null }, fallbackLng: 'en', saveMissing: true, interpolation: { escapeValue: false // not needed for react as it escapes by default } }) export default i18n
测试环境中,我尝试Mock i18n相关逻辑,使用了如下代码:
jest.mock('react-i18next', () => ({ // this mock makes sure any components using the translate hook can use it without a warning being shown useTranslation: () => { return { t: (str: string) => str, i18n: { changeLanguage: () => new Promise(() => {}) } } }, initReactI18next: { type: '3rdParty', init: () => {} } }))
但测试仍尝试调用i18next的HTTP后端,收到MSW的警告:
console.warn [MSW] Warning: captured a request without a matching request handler: • GET http://localhost/locales/en/translation.json
请问如何正确Mock i18next,以阻止其调用HTTP后端?
解决方案
方法1:Mock整个i18next核心模块
当前仅Mock了react-i18next,但i18next本身的Backend初始化逻辑仍在执行。直接Mock i18n核心模块,从根源上跳过Backend加载:
// Mock i18next核心模块 jest.mock('i18next', () => { const mockI18n = { use: jest.fn().mockReturnThis(), // 链式调用返回自身 init: jest.fn().mockResolvedValue(true), // 模拟初始化成功 t: (str) => str, // 直接返回翻译键 changeLanguage: jest.fn().mockResolvedValue(true), }; return mockI18n; }); // 保留react-i18next的Hook Mock jest.mock('react-i18next', () => ({ useTranslation: () => ({ t: (str) => str, i18n: { changeLanguage: () => Promise.resolve() } }), initReactI18next: { type: '3rdParty', init: jest.fn() } }));
方法2:覆盖i18n配置,改用内存翻译资源
复用现有i18n实例,但在测试前重新初始化,移除Backend依赖,直接提供内存中的翻译数据:
import i18n from './path/to/your/i18n'; beforeAll(() => { i18n.init({ resources: { en: { translation: { // 测试所需的翻译键值对,例: 'hello': 'Hello' } } }, fallbackLng: 'en', interpolation: { escapeValue: false }, // 禁用Backend和detector backend: null, detection: null }); });
方法3:Mock i18next-http-backend模块
直接Mock后端插件,让它不发起真实HTTP请求:
jest.mock('i18next-http-backend', () => () => ({ type: 'backend', init: jest.fn(), read: jest.fn().mockResolvedValue({}) // 模拟读取翻译文件成功,返回空对象或测试数据 }));
内容的提问来源于stack exchange,提问作者Hermann.Gruber
相关产品推荐
相关产品推荐

