React-i18next: provided mock example not working for i18n.addResourceBundle

Created on 18 Feb 2019  ·  7Comments  ·  Source: i18next/react-i18next

First of all, congrats for the awesome package! we started using it in our projects and it saved us so much time.
However we are having some issues with the testing, we are using jest + enzyme in a react project + redux.

We implemented react-i18next like so in a lib/i18n file:

import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import { reactI18nextModule } from 'react-i18next';
import moment from 'moment';
import 'moment/locale/nl';

i18n
  .on('languageChanged', (lng) => {
    moment.locale(lng);
  })
  .use(LanguageDetector)
  .use(reactI18nextModule)
  .init({
    fallbackLng: 'en',
    debug: true,

    react: {
      wait: true,
    },
  });

export default i18n;

we created a __mocks__ folder and used your example __mocks__/react-18next.js we are seeing that once we import i18n and try to manipulate its properties from a non-jsx file this mock is not called. Our use case is the following:

We have an action that requests all the translations and uses the i18n.addResourceBundle in the response to set all the translations.

in this action, we import the ../lib/i18n.js file created for the effect, but once we start testing our action we keep on getting the following errors

```
TypeError: _i18next.default.on is not a function

   6 |
   7 | i18n
>  8 |   .on('languageChanged', (lng) => {
     |    ^
   9 |     moment.locale(lng);
  10 |   })
  11 |   .use(LanguageDetector)

  at Object.on (src/lib/i18n.js:8:4)
  at Object.<anonymous> (src/actions/translation.js:2:1)
  at Object.<anonymous> (src/actions/translation.test.js:2:1)

```

we detected that the __mocks__/react-i18next.js does not get called, but if we create a __mocks__/i18next.js file it will mock the imported i18n instance what makes sense since within the configuration file lib/i18n.js we are importing it import i18n from 'i18next'; but once again the provided mock file within your project does not seem to work.

We are considering the following scenarios and would like to ask for your opinion:

  • migrate our fetch action to i18next-xhr-backend and we would like to ask you if this would fix the issue? since we no longer are going to import the config file and therefore no need to mock it, but we would lose our redux action logging functionality since we are using redux store to keep track of the user actions.
  • mock the file correctly in order to maintain the current functionality and for this, we would like to ask if anyone already experienced the same behavior.

Occurs in react-i18next version
"react-i18next": "^9.0.2",

I created a StackOverflow question but I thought it would be a good idea to do it here as well. (https://stackoverflow.com/questions/54746378/how-to-mock-i18n-addresourcebundle)

Most helpful comment

I was able to fix it by just mocking my lib/i18n.js file

jest.mock('../lib/i18n', () => ({
  addResourceBundle: jest.fn(),
}));

this way once it will mock the whole file implementation.
Thank you for the help 👍

All 7 comments

The provided mock is a sample mock -> means it's very basic and not covering 100% of i18next's functionality...you will add/extend what you need.

eg. you might build some i18next mock (eg. what we use for some tests: https://github.com/i18next/react-i18next/blob/master/test/useTranslation.ready.spec.js#L7)

I'm trying in a lot of different ways to mock it but always without success

FAIL  src/actions/translation.test.js
  ● Test suite failed to run

    TypeError: Cannot read property 'use' of undefined

      15 |   .use(reactI18nextModule)
      16 |   .init({
    > 17 |     fallbackLng: 'en',
         |     ^
      18 |     debug: false,
      19 |     react: {
      20 |       wait: true,

      at Object.debug (src/lib/i18n.js:17:5)
      at Object.<anonymous> (src/actions/translation.js:2:1)
      at Object.<anonymous> (src/actions/translation.test.js:2:1)

  console.log src/lib/i18n.js:8
    { withNamespaces: [Function: withNamespaces],
      Trans: [Function: Trans],
      NamespacesConsumer: [Function: NamespacesConsumer],
      Interpolate:
       { [Function: WithContext]
         WrappedComponent: [Function: InterpolateComponent],
         displayName: 'WithMergedOptions(InterpolateComponent)' },
      I18nextProvider: [Function: I18nextProvider],
      loadNamespaces: [Function: loadNamespaces],
      reactI18nextModule: { type: '3rdParty', init: [Function: init] },
      setDefaults: [Function: setDefaults],
      getDefaults: [Function: getDefaults],
      setI18n: [Function: setI18n],
      getI18n: [Function: getI18n],
      **on: [Function: on],
      use: [Function: use],
      init: [Function: init] }**

This always returns undefined for i18n

And since we start importing lib/i18n within the action we are getting this error related to the backend plugin, so we are definitely missing something do you any idea how to solve this?

Error: Error: connect ECONNREFUSED 127.0.0.1:80
        at Object.dispatchError (/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:65:19)
        at Request.client.on.err (/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:676:20)
        at Request.emit (events.js:185:15)
        at Request.onRequestError (/node_modules/request/request.js:881:8)
        at ClientRequest.emit (events.js:180:13)
        at Socket.socketErrorListener (_http_client.js:395:9)
        at Socket.emit (events.js:180:13)
        at emitErrorNT (internal/streams/destroy.js:64:8)
        at process._tickCallback (internal/process/next_tick.js:178:19) undefined

do not import the real i18next instance...mock it away...i18n is not a concern you should test in you components.

I was able to fix it by just mocking my lib/i18n.js file

jest.mock('../lib/i18n', () => ({
  addResourceBundle: jest.fn(),
}));

this way once it will mock the whole file implementation.
Thank you for the help 👍

If you like this module don’t forget to star this repo. Make a tweet, share the word or have a look at our https://locize.com to support the devs of this project -> there are many ways to help this project :pray:

Was this page helpful?
0 / 5 - 0 ratings