【问题标题】:Mocking useTranslation for i18n in JEST not working在 JEST 中模拟 i18n 的 useTranslation 不起作用
【发布时间】:2019-10-09 12:28:13
【问题描述】:

我的反应组件使用来自 i18next 的翻译,我正在尝试使用 JEST 为它创建测试。但是,没有任何内容被翻译,我尝试在下面模拟 useTranslation 函数:

const useMock : any = [(k: any) => k, {}];
useMock.t = (k: any) => k;
useMock.i18n = {};

jest.mock('react-i18next', () => ({
  // this mock makes sure any components using the translate HoC receive the t function as a prop
  /* tslint:disable-next-line:variable-name */
  useTranslation: () => useMock,
}));

我做错了什么?

【问题讨论】:

    标签: typescript jestjs i18next react-i18next ts-jest


    【解决方案1】:

    使用以下内容创建一个模拟文件:__mocks__/react-i18next.useTranslation.js

    module.exports = () => {
      return () => ({
        t: key => key
      })
    }
    

    【讨论】:

      【解决方案2】:

      创建一个文件__mocks__/react-i18next.js(文件夹__mocks__node_modules旁边,在同一个父文件夹中),包含:

      module.exports = {
        useTranslation: () => ({
          t: key => key,
        }),
      }
      

      在您的测试脚本中,正常导入useTranslation,但定义要使用的模拟。

      import {useTranslation} from 'react-i18next'
      /* Other imports and code */
      
      jest.mock('react-i18next')
      /* Your test code using useTranslation */
      

      【讨论】:

      • 就我而言,使用您的代码 sn-p 创建__mocks__/react-i18next.js 足以消除此警告。我不必在测试中显式调用jest.mock('react-i18next') 或导入useTranslation
      【解决方案3】:

      我分享我的配置,希望对你有帮助

      我的文件夹是这样的:

      我的模拟是这样的:

      react-i18next.js
      
      const React = require('react');
      const reactI18next = require('react-i18next');
      let root = __dirname;
      var fs = require('fs');
      
      //console.log(root.replace("src\\__mocks__","public\\assets\\i18n\\{{ns}}.json"))
      const hasChildren = (node) => node && (node.children || (node.props && node.props.children));
      
      const getChildren = (node) =>
          node && node.children ? node.children : node.props && node.props.children;
      
      const renderNodes = (reactNodes) => {
          if (typeof reactNodes === 'string') {
              return reactNodes;
          }
      
          return Object.keys(reactNodes).map((key, i) => {
              const child = reactNodes[key];
              const isElement = React.isValidElement(child);
      
              if (typeof child === 'string') {
                  return child;
              }
              if (hasChildren(child)) {
                  const inner = renderNodes(getChildren(child));
                  return React.cloneElement(child, { ...child.props, key: i }, inner);
              }
              if (typeof child === 'object' && !isElement) {
                  return Object.keys(child).reduce((str, childKey) => `${str}${child[childKey]}`, '');
              }
      
              return child;
          });
      };
      
      let language = "en"
      const useMock = [(k) => k, {}];
      let traduccions = root.replace("src\\__mocks__", `public\\assets\\i18n\\commons\\${language}.json`)
      
      let changeLanguage = (lng = "en") => {
          useMock.language = lng;
      }
      
      useMock.i18n = { 
          ns: ['commons'],
          defaultNS: 'commons',
          changeLanguage,
          language,
      };
      useMock.t = (k) => { 
          const result =()=> fs.readFileSync(traduccions,"utf8", function (err, data) {
              if (err) {
                 return console.error(err);
              }
             return data.toString()
           });  
          let termsToSearch = k.replace(`${useMock.i18n.defaultNS}:`,'').split(".")
          let res =JSON.parse(result());
          termsToSearch.forEach(element => {
               res=res[element];
          });
          return res;
      };
      
      
      
      /**
       * commons:language.language
       */
      
      
      
      module.exports = {
          // this mock makes sure any components using the translate HoC receive the t function as a prop
          withTranslation: () => (Component) => (props) => <Component t={(k) => k} {...props} />,
          Trans: ({ children }) =>
              Array.isArray(children) ? renderNodes(children) : renderNodes([children]),
          Translation: ({ children }) => children((k) => k, { i18n: {} }),
          useTranslation: () => useMock,
      
          // mock if needed
          I18nextProvider: reactI18next.I18nextProvider,
          initReactI18next: reactI18next.initReactI18next,
          setDefaults: reactI18next.setDefaults,
          getDefaults: reactI18next.getDefaults,
          setI18n: reactI18next.setI18n,
          getI18n: reactI18next.getI18n,
      };
      

      主要是 i18n 的文档,我只是添加了显示正确翻译的方式

      https://react.i18next.com/misc/testing https://github.com/i18next/react-i18next/blob/master/example/test-jest/src/__mocks__/react-i18next.js

      【讨论】:

        猜你喜欢
        • 2020-03-05
        • 1970-01-01
        • 2020-09-24
        • 1970-01-01
        • 2019-06-10
        • 2020-03-11
        • 2021-01-10
        • 2019-01-24
        • 2020-08-13
        相关资源
        最近更新 更多