首页 > 解决方案 > 如何模拟 i18n.addResourceBundle?

问题描述

我在测试 i18next 时遇到了一些问题,我们在反应项目 + redux 中使用 jest + 酶。

我们在一个文件react-i18next中这样实现:lib/i18n

import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import { reactI18nextModule } from 'react-i18next';
import moment from 'moment';
import 'moment/locale/nl';

i18n
  .on('languageChanged', (lng) => {
    moment.locale(lng);
  })
  .use(LanguageDetector)
  .use(reactI18nextModule)
  .init({
    fallbackLng: 'en',
    debug: true,

    react: {
      wait: true,
    },
  });

export default i18n;

我们创建了一个__mocks__文件夹并使用了(https://github.com/i18next/react-i18next)中提供的示例,__mocks__/react-18next.js我们看到,一旦我们i18n从非 jsx 文件导入并尝试操作其属性,就不会调用该模拟。我们的用例如下:

我们有一个请求所有翻译的操作,并i18n.addResourceBundle在响应中使用 来设置所有翻译。

在这个动作中,我们导入了../lib/i18n.js为效果创建的文件,但是一旦我们开始测试我们的动作,我们就会不断收到以下错误

TypeError: _i18next.default.on is not a function

       6 |
       7 | i18n
    >  8 |   .on('languageChanged', (lng) => {
         |    ^
       9 |     moment.locale(lng);
      10 |   })
      11 |   .use(LanguageDetector)

      at Object.on (src/lib/i18n.js:8:4)
      at Object.<anonymous> (src/actions/translation.js:2:1)
      at Object.<anonymous> (src/actions/translation.test.js:2:1)

我们检测到__mocks__/react-i18next.js没有被调用,但是如果我们创建一个__mocks__/i18next.js文件,它将模拟导入的i18n实例,这是有意义的,因为在配置文件lib/i18n.js中我们正在导入它,import i18n from 'i18next';但您的项目中提供的模拟文件似乎再次不起作用。

我们正在考虑以下场景并想征求意见: - 将我们的 fetch 操作迁移到 i18next-xhr-backend,我们想问您这是否可以解决问题?因为我们不再要导入配置文件,因此不需要模拟它,但是我们将失去我们的 redux 操作日志记录功能,因为我们使用 redux store 来跟踪用户操作。- 正确模拟文件以保持当前功能,为此,我们想询问是否有人已经经历过相同的行为。

发生在 react-i18next 版本中 "react-i18next": "^9.0.2",

标签: reactjsi18nextreact-i18next

解决方案


我已经设法克服了这个问题,我相信。

将模拟中的第 35 行替换为:

var selectedLanguage = "en-gb";
useMock.i18n = {
    language: selectedLanguage,
    changeLanguage: (lng) => selectedLanguage = lng,
};

推荐阅读