Search code examples
react-nativejestjsreact-i18next

How to test react-native components which are using react-i18next?


I'm trying to use jest to start testing an established RN app. The majority of the components are wrapped in withNamespaces provided by react-i18next.

When i run tests i have this error:

 FAIL  tests/setting.test.js
  ● Test suite failed to run

    TypeError: Cannot read property 'type' of undefined

      4 | 
      5 | i18n
    > 6 |   .use(initReactI18next)
        | ^
      7 |   .init({
      8 |     fallbackLng: 'en',
      9 |     resources: {

      at I18n.use (node_modules/i18next/dist/commonjs/i18next.js:260:16)
      at Object.<anonymous> (config/i18nForTest.js:6:1)
      at Object.<anonymous> (tests/setting.test.js:5:43)

I followed the doc example and what i've done basically is : made i18n config for tests :

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


i18n
  .use(initReactI18next)
  .init({
    fallbackLng: 'en',
    resources: {
      en: {},
      fr: {}
    },
    // have a common namespace used around the full app
    ns: ['translations'],
    defaultNS: 'translations',

    debug: true,

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

export default i18n;

then wrote some tests:

import 'react-native';
import React from 'react';
import renderer from 'react-test-renderer';
import {I18nextProvider} from 'react-i18next';
import i18n from 'config/i18nForTest';
import Settings from 'containers/Settings';

it('Does Settings renders correctly?', () => {
  const tree = renderer
    .create(
      <I18nextProvider i18n={i18n}>
        <Settings t= {key => key} />
      </I18nextProvider>,
    )
    .toJSON();
  expect(tree).toMatchSnapshot();
});

you can find here my jest config in package.json:



"jest": {
    "setupFiles": ["<rootDir>/jest.setup.js"],
    "preset": "react-native",
    "testMatch": [
      "<rootDir>/tests/**/*.test.js?(x)",
      "<rootDir>/src/**/*.test.js"
    ],
    "transformIgnorePatterns": ["node_modules/(?!(@react-native-community|react-navigation|react-native))"
    ],
    "transform": {
      "^.+\\.(js)$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
    }
  },

THANKS!


Solution

  • I finally found a solution for my problem. I think the testing example provided in the doc is for v10 and i'm using v9. So i have modified the i18n config test to use reactI18nextModule so its like this now:

    import i18n from 'i18next';
    import { initReactI18next } from 'react-i18next';
    import { reactI18nextModule } from 'react-i18next';
    
    
     i18n
      .use(reactI18nextModule)
      .init({
        fallbackLng: 'en',
        resources: {
          en: {},
          fr: {}
        },
        // have a common namespace used around the full app
        ns: ['translations'],
        defaultNS: 'translations',
    
        debug: true,
    
        interpolation: {
          escapeValue: false, // not needed for react!!
        },
      });
    
    export default i18n;
    

    after that now i can omit i18nProvider in the testing components like this:

    import 'react-native';
    import React from 'react';
    import renderer from 'react-test-renderer';
    import {I18nextProvider} from 'react-i18next';
    import i18n from 'config/i18nForTest';
    import {Settings} from 'containers/Settings'; // to get redux connected component import Setting without {}
    
    
    it('Does Settings renders correctly?', () => {
      const tree = renderer
        .create(
            <Settings t={key => key} />
             )
        .toJSON();
      expect(tree).toMatchSnapshot();
    });