react-i18next:: 您需要使用 initReactI18next 传递 i18next 实例,在 Jest 单元测试中抛出警告

Rya*_*P13 19 internationalization i18next reactjs react-i18next

react-i18next在我的应用程序中使用效果很好,但是当我针对我的组件运行单元测试时:

const OptionList = ({
  definition,
  name,
  status = EMutationStatus.IDLE,
  onChange = () => null,
  value = [],
}: IOptionListProps): React.ReactElement => {
  const { t } = useTranslation();
  const { options } = definition;
  return (
    <Select
      name={name}
      data-testid="optionList"
      id={name}
      placeholder={t('COMMON.PLEASE_SELECT')}
      onChange={e => onChange(e.currentTarget.value)}
      defaultValue={value[0]}
      disabled={status === EMutationStatus.LOADING}
    >
      {options.map((option: string): React.ReactElement => {
        return (
          <option key={option} value={option}>
            {option}
          </option>
        );
      })}
    </Select>
  );
};
Run Code Online (Sandbox Code Playgroud)

运行单元测试套件时它会抛出以下警告:

react-i18next:: You will need to pass in an i18next instance by using initReactI18next

我有点迷失了,因为我已经react-i18nextreact-testing-library.

我的i18n测试实例:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

i18n.use(initReactI18next).init({
  lng: 'cimode', // setting lng to 'cimode' will cause the t function to always return the key.
  // ----- ^
  // have a common namespace used around the full app
  ns: ['translations'],
  defaultNS: 'translations',

  interpolation: {
    escapeValue: false, // not needed for react!!
  },

  resources: { en: { translations: {} }, zh: { translations: {} }, th: { translations: {} } },
});

export default i18n;
Run Code Online (Sandbox Code Playgroud)

我的自定义渲染函数如下:

export function render(
  ui: RenderUI,
  { wrapper, ...options }: RenderOptions = {}
): RenderResult {
  if (!wrapper) {
    // eslint-disable-next-line no-param-reassign
    wrapper = ({ children }) => (
      <BrowserRouter>
        <ChakraProvider resetCSS theme={theme}>
          <QueryClientProvider client={testQueryClient}>
            <I18nextProvider i18n={i18n}>{children}</I18nextProvider>
          </QueryClientProvider>
        </ChakraProvider>
      </BrowserRouter>
    );
  }

  return defaultRender(ui, { wrapper, ...options });
}
Run Code Online (Sandbox Code Playgroud)

这只是一个警告,所以没什么大不了的,但我很困惑为什么会在这里抛出这个问题,因为我相信我已经按照此处文档中的概述设置了提供程序:

https://react.i18next.com/misc/testing

有人帮我摆脱这个警告吗?

更新

useTranslation我尝试从同一测试链接添加建议的钩子玩笑模拟:

jest.mock('react-i18next', () => ({
  // this mock makes sure any components using the translate hook can use it without a warning being shown
  useTranslation: () => {
    return {
      t: (str: string): string => str,
    };
  },
}));
Run Code Online (Sandbox Code Playgroud)

但我仍然收到同样的警告。

小智 12

这对我有用。您可以在官方文档中找到更多信息。

jest.mock('react-i18next', () => ({
  // this mock makes sure any components using the translate hook can use it without a warning being shown
  useTranslation: () => {
    return {
      t: (str) => str,
      i18n: {
        changeLanguage: () => new Promise(() => {}),
      },
    };
  },
}));
Run Code Online (Sandbox Code Playgroud)


小智 8

您是否尝试在 beforeEach 钩子内部调用i18n.init()?i18n 应该是您实例化的 i18n 实例的实例。

唯一的区别是,在我的例子中,我已命名 i18n 实例的导出。

import { i18n } from "../../services/Internationalization";

describe('testSuite', () => {
   beforeEach(() => {
    i18n.init();
  });
});
Run Code Online (Sandbox Code Playgroud)

在 i18n.ts 中我必须这样做:

i18n.use(initReactI18Next).init(...some configs);
export { i18n };
Run Code Online (Sandbox Code Playgroud)