jest.mock('react-i18next', () => ({// this mock makes sure any components using the translate HoC receive the t function as a propwithTranslation: () => Component => {Component.defaultProps = { ...Component.defaultProps,t: (i18nKey) => i18nKey };// or with TypeScript://Component.defaultProps = { ...Component.defaultProps, t: (i18nKey: string) => i18nKey };return Component; },}));
Or, when using the useTranslation hook instead of withTranslation, mock it like:
jest.mock('react-i18next', () => ({// this mock makes sure any components using the translate hook can use it without a warning being shownuseTranslation: () => {return {t: (i18nKey) => i18nKey,// or with TypeScript://t: (i18nKey: string) => i18nKey, i18n: {changeLanguage: () =>newPromise(() => {}), }, }; }, initReactI18next: { type:'3rdParty',init: () => {}, }}));
or, you can also spy the t function:
// implementationimport React from'react';import { useTranslation } from'react-i18next';exportdefaultfunctionCustomComponent() {const { t } =useTranslation();return <div>{t('some.key', { some:'variable' })}</div>;}// testimport React from'react';import { mount } from'enzyme';import UseTranslationWithInterpolation from'./UseTranslationWithInterpolation';import { useTranslation } from'react-i18next';jest.mock('react-i18next', () => ({ useTranslation:jest.fn(),}));it('test render', () => {constuseTranslationSpy= useTranslation;consttSpy=jest.fn((str) => str);useTranslationSpy.mockReturnValue({ t: tSpy, i18n: {changeLanguage: () =>newPromise(() => {}), }, });constmounted=mount(<UseTranslationWithInterpolation />);// console.log(mounted.debug());expect(mounted.contains(<div>some.key</div>)).toBe(true);// If you want you can also check how the t function has been called,// but basically this is testing your mock and not the actual code.expect(tSpy).toHaveBeenCalledTimes(1);expect(tSpy).toHaveBeenLastCalledWith('some.key', { some:'variable' });});
Alternatively, you could also test I18next without stubbing anything, by providing the correct configuration and fully wrapping your container in the provider.
Example configuration for testing
import i18n from'i18next';import { initReactI18next } from'react-i18next';i18n.use(initReactI18next).init({ lng:'en', fallbackLng:'en',// have a common namespace used around the full app ns: ['translationsNS'], defaultNS:'translationsNS', debug:true, interpolation: { escapeValue:false,// not needed for react!! }, resources: { en: { translationsNS: {} } }, });exportdefault i18n;
As translations aren't provided, this.props.i18n.language will be undefined. In case your application relies on that value you can mock resources by adding these lines to the object passed to init: