【问题标题】:React Testing Lib: Best practice on querying translated strings?React 测试库:查询翻译字符串的最佳实践?
【发布时间】:2021-01-13 19:14:05
【问题描述】:

我正在与我的团队讨论在查询翻译文本时什么是最佳做法。

由于非开发人员(翻译人员)可以修改这些文本,因此我们不希望每次翻译更改都会破坏我们的测试。但是我的一部分队友认为我们应该继续使用纯字符串,所以我们的测试类似于用户行为...... 在我们当前的代码中,我们正在做这样的事情来找到一个按钮:

const buttonCHF = await screen.findByText('My button textl');

我们目前正在使用 react-intl,所以我提出了一个解决方案,可以像这样找到相同的按钮:

const buttonText = getNodeText(<FormatteMessage id="buttonText" />);
const buttonCHF = await screen.findByText(buttonText);

我认为这将使测试更有弹性,而不会破坏使测试尽可能与用户行为最相似的规则,毕竟,我们将查询与用户相同的文本,同时避免无法维护的字符串。你怎么看?

【问题讨论】:

  • 你能有一个只输出输入字符串的无操作“翻译”,然后对此进行测试吗?这样,您就可以不断测试用于查找真实翻译的 ID,以便了解它们是否意外更改。

标签: reactjs unit-testing testing jestjs react-testing-library


【解决方案1】:

在我的团队中,我们使用 react-i18next,我们像这样模拟翻译功能(命名为 t):

// mock intl module
// in tests always return the translation key itself
jest.mock('i18n', () => ({
  addResourceBundle: jest.fn(),
  loadNamespaces: jest.fn(),
  t: (key) => key,
  language: 'en',
}));

// mock the hook (used like so in components :
// const { t } = useTranslation(namespaces);
jest.mock('react-i18next', () => ({
  useTranslation: () => ({ t: (key) => key, i18n: { language: 'en', changeLanguage: jest.fn() } }),
}));

你应该可以用 react-intl 做一些等效的事情。

此代码放置在项目根目录的 setupTests.js 中,因为我们使用 create-react-app (https://create-react-app.dev/docs/running-tests/#srcsetuptestsjs),但如果您不这样做,您仍然应该能够设置测试“预运行文件”,您可以在其中全局模拟事物。

在我们的测试中,我们使用getByText函数检查翻译键是否正确,所以即使实际显示的文本发生变化,我们的测试仍然通过。

例如

<Button>{t('translationKey')}</Button>

...将呈现为

<button>translationKey</button>

...在我们的测试中,所以

screen.getByText('translationKey')

...会找到我们的按钮。

【讨论】:

  • 是否需要单独模拟react-i18next,而不是让它使用模拟的i18n?这似乎很尴尬;如果你重构为切换到 HOC 并从 props 中得到t,你的测试会突然停止工作。
  • 好点...我尝试在 i18n 模拟中添加 useTranslation,它工作正常并且看起来更干净。我会深入研究这个!
  • 能否请您添加一个示例 jest 文件。
猜你喜欢
  • 2013-04-22
  • 1970-01-01
  • 2021-09-30
  • 1970-01-01
  • 1970-01-01
  • 2015-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多