使用 Typescript 和 i18next 用 Jest 测试日期对象

Testing Date Object with Jest using Typescript and i18next

包括一个本地化库,我的组件中有一个日期对象,如下所示:

  getDate = () => {
    const { t } = this.props;
    return new Date().toLocaleString(t('locale.name'), {
      weekday: "long",
      month: "long",
      day: "numeric",
    });
  };

当我尝试 运行 测试时,出现错误:

RangeError: Invalid language tag: language.name at Date.toLocaleString ()

  15 |   getDate = () => {
  16 |     const { t } = this.props;
> 17 |     return new Date().toLocaleString(t('language.name'), {
     |                       ^
  18 |       weekday: "long",
  19 |       month: "long",
  20 |       day: "numeric",

所以它无法识别 i18n 语言环境。这与我嘲笑 i18n 的方式有关吗?

我当前的设置:

反应-i18next.ts:

jest.mock('i18next', () => ({
  use: () => {
    return {
      init: () => { }
    };
  },
  t: k => k
}));

我的jest.config:

module.exports = {
  verbose: true,
  roots: ["<rootDir>"],
  testRegex: "/__tests__/.*\.(test|spec)\.tsx?",
  transform: {
    "^.+\.tsx?$": "ts-jest",
  },
  moduleNameMapper: {
    "react-i18next": "<rootDir>/__tests__/__mock__/react-i18next.ts"
  },
};

i18n.ts

import i18n from "i18next";
import {initReactI18next} from "react-i18next";
import english from "./locales/en/common.json";
import french from "./locales/fr/common.json";

i18n.use(initReactI18next).init({
  lng: 'en',
  resources: {
    fr: {
      translation: french,
    },
    en: {
      translation: english,
    },
  },
  interpolation: {
    escapeValue: false,
  },
  fallbackLng: ["en"]
});

export default i18n;

你对 t 的模拟使其成为 return 密钥本身,因此,toLocaleString 得到 language.name 作为一种语言,并且它抛出 "Invalid language tag".

我的日期格式本地化方法是使用 formatting 方法按区域设置日期格式。

// i18next.config.js

...
{
  interpolation: {
    format: (value, format, lng) => {
      if (value instanceof Date) {
        const cloneDate = new Date(value);

        return cloneDate.toLocaleString(lng, mapFormatToLocale[format]);
      }
      return value;
    };
  }
}
...

const mapFormatToLocale = {
  YYYYmmdd: {
    weekday: 'long',
    month: 'long',
    day: 'numeric',
  },
};
// locale.en.json 

{
  "MY_DATE": "My Date {{date, YYYYmmdd}}"
}

// usage of the date locatization

t('MY_DATE', {date: new Date()});

此方法最酷的部分是您在翻译 json 文件中定义日期格式样式,这意味着您可以根据需要更改每种语言。

此方法反转语言环境和日期之间的依赖关系,并且将与您的模拟一起使用,因为您的模拟将只是 return 翻译键。