使用 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 翻译键。
包括一个本地化库,我的组件中有一个日期对象,如下所示:
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 翻译键。