react-native-i18n: Jest Error Message - TypeError: Cannot read property 'languages' of undefined

 FAIL  __tests__\index.android.js
  ● Test suite failed to run

    TypeError: Cannot read property 'languages' of undefined
      
      at Object.<anonymous> (node_modules/react-native-i18n/index.js:7:31)
      at Object.<anonymous> (src/tools.js:8:34)
      at Object.<anonymous> (src/App.js:5:12)

tests\index.android.js

import 'react-native';
import React from 'react';
import App from '../src/App';
import renderer from 'react-test-renderer';
it('renders correctly', () => {
	const tree = renderer.create(
		<App />
	);
});

src/tools.js

import I18n from 'react-native-i18n';
import en from '../res/locales/en';
import es from '../res/locales/es';
import zh from '../res/locales/zh';
I18n.fallbacks = true;
I18n.defaultLocale = 'en';
I18n.translations = { en, es, zh };
export function trans(key) {
	return I18n.t(key);
}

Used in code in this format:

import { trans } from './tools.js';
console.log(trans('key.from.json.lang.files'));

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 27
  • Comments: 34

Most upvoted comments

I just to do like this, it worked. I’m using version v2.0.2:

jest.mock('react-native-i18n', () => {
  return {};
});

Inside my jest setup , I did jest.mock('react-native-i18n', () => ({ t: jest.fn((translation) => translation), }));

This will replace the actual text with the i18n key , which I suppose is good for snapshot testing.

I published the 2.0.5 release with a test in the /example folder: https://github.com/AlexanderZaytsev/react-native-i18n/tree/master/example/src

I did something similar to @yspychala, but with a different library (react-native-doc-viewer). Here’s a breakdown of what happened for me to get tests to pass.

Problem

  • I just detached my expo app (wish me luck). Upon running my Jest tests for my components, I was receiving an error stating the following
    TypeError: Cannot read property 'openDoc' of undefined

Solution

  • I mocked the react-native-doc-viewer package in my testing env file which is pulled in as a setup file when run my tests.
  • My package.json contains this block of code:
"jest": {
    "preset": "jest-expo",
    "setupFiles": [
      "./test/env.js"
    ]
  }, 
  • In my env.js file I mock the package like so to expose the package globally during tests :
const OpenFileMock = jest.mock('react-native-doc-viewer', () => {
  return {
    openFile: jest.fn(() => {})
  }
})

global.OpenFile = OpenFileMock

Notes

All my tests are now passing. Hope this helps with anyone’s issues. Please tag me if you have any questions.

I fix this problem here

@herman-rogers’ solution looks good, I only had to add another property to the mocked object to get rid of currentLocale is not a function error:

const I18nMock = jest.mock('react-native-i18n', () => {
  return {
    t: jest.fn(translation => translation), // you may have to change this function
    currentLocale: jest.fn(() => 'en'), // I added this line
  };
});

Cool thanks @wontwon - saved me loads of time this morning. Finally got it working I’ll outline here what I did for react-i18n (although its basically the exact same as @wontwon’s answer)

Problem

TypeError: Cannot read property 'languages' of undefined inside all of my react jest snapshot.

Solution

  • Add a testEnvironment file to your package.json. Mine is stored in my root directory alongside package.json.
  "jest": {
    "preset": "react-native",
    "setupFiles": [
      "./config/testEnvironment.js"
    ]
  }
  • Next add the mocked ‘react-native-i18n’ to the testEnvironment.js
const I18nMock = jest.mock('react-native-i18n', () => {
  return {
    // translation passed in here is the
    // string passed inside your template
    // I18n.t('yourObjectProperty')
    t: jest.fn((translation) => {
      // This function is something custom I use to combine all
      // translations into one large object from multiple sources
      // appTranslations is basically just a large object
      // { en: { yourObjectProperty: 'Your Translation' } }
      const appTranslations = combineTranslations(
        TestFormTranslation,
        TestSecondFormTranslation,
      );
      // I use english as the default to return translations to the template. 
      // This last line returns the value of your translation
      // by passing in the translation property given to us by the template.
      return appTranslations.en[translation];
    }),
  };
});

global.I18n = I18nMock;

Notes

  • For the above method you can just return a string (“MockTranslations”, etc), or the translation property. I just went for the real translations so I didn’t have to rebake my snapshots.

@jaimeagudo react-native unlink/react-native link doesn’t work for me either (w/ RN@0.46.2)

I use this solution for now :

jest.mock('react-native-i18n', () => {
  const i18njs = require('i18n-js');
  const en = require('../app/i18n/locales/en');
  i18njs.translations = {en}; // Optional ('en' is the default)

  return {
     t: jest.fn((k, o) => i18njs.t(k, o)),
  };
});

Hi @zoontek, I am using RN version 0.45.1 and react-native-i18n version 2.0.5. and I am still getting:

TypeError: Cannot read property 'getLanguages' of undefined

I tried to un-link and link the package, it did not solve the problem I want to avoid unnecessary mocking only for JEST test, since it is a source for errors and maintenance headache

I don’t understand why people recommend to unlink/link the package when it fails on Jest, did I miss something ?

for now, this is what I did:

  1. add file react-native-i18n.js to mock folder with:
const I18nMock = jest.mock('react-native-i18n', () => ({
    t: jest.fn(translation => translation),
    currentlLocale: jest.fn(() => 'en'),
}));

global.I18n = I18nMock;

in my package.json I added into the jest configuration section:

"jest": {
    ...
    "setupFiles": [
        "<rootDir>/__mock__/react-native-i18n.js",
        ...-other mock packages...
    ],
    ...
}

I tried to follow the example @zoontek added but with no luck.

I also have nonworking react-native link for this package and I linked it manually. It’s awful.

i just solved…it was my error… it seems that it didnt link properly with react-native link so i just had to link it manually, my bad

any news on this? i have the same problem 😦