Reputation: 345
My react component uses translations from i18next and I'm trying to create tests for it using JEST. However, nothing is getting translated and I have tried mocking the useTranslation function below:
const useMock : any = [(k: any) => k, {}];
useMock.t = (k: any) => k;
useMock.i18n = {};
jest.mock('react-i18next', () => ({
// this mock makes sure any components using the translate HoC receive the t function as a prop
/* tslint:disable-next-line:variable-name */
useTranslation: () => useMock,
}));
What am I doing wrong?
Upvotes: 6
Views: 23671
Reputation: 11
Try like this:
jest.mock('react-i18next', () => ({
useTranslation: () => ({ t: () => ['key'] }),
Trans: () => jest.fn(),
t: () => jest.fn(),
}));
Upvotes: 1
Reputation: 64
i share my config i hope that it can help you
my mocks is this :
react-i18next.js
const React = require('react');
const reactI18next = require('react-i18next');
let root = __dirname;
var fs = require('fs');
//console.log(root.replace("src\\__mocks__","public\\assets\\i18n\\{{ns}}.json"))
const hasChildren = (node) => node && (node.children || (node.props && node.props.children));
const getChildren = (node) =>
node && node.children ? node.children : node.props && node.props.children;
const renderNodes = (reactNodes) => {
if (typeof reactNodes === 'string') {
return reactNodes;
}
return Object.keys(reactNodes).map((key, i) => {
const child = reactNodes[key];
const isElement = React.isValidElement(child);
if (typeof child === 'string') {
return child;
}
if (hasChildren(child)) {
const inner = renderNodes(getChildren(child));
return React.cloneElement(child, { ...child.props, key: i }, inner);
}
if (typeof child === 'object' && !isElement) {
return Object.keys(child).reduce((str, childKey) => `${str}${child[childKey]}`, '');
}
return child;
});
};
let language = "en"
const useMock = [(k) => k, {}];
let traduccions = root.replace("src\\__mocks__", `public\\assets\\i18n\\commons\\${language}.json`)
let changeLanguage = (lng = "en") => {
useMock.language = lng;
}
useMock.i18n = {
ns: ['commons'],
defaultNS: 'commons',
changeLanguage,
language,
};
useMock.t = (k) => {
const result =()=> fs.readFileSync(traduccions,"utf8", function (err, data) {
if (err) {
return console.error(err);
}
return data.toString()
});
let termsToSearch = k.replace(`${useMock.i18n.defaultNS}:`,'').split(".")
let res =JSON.parse(result());
termsToSearch.forEach(element => {
res=res[element];
});
return res;
};
/**
* commons:language.language
*/
module.exports = {
// this mock makes sure any components using the translate HoC receive the t function as a prop
withTranslation: () => (Component) => (props) => <Component t={(k) => k} {...props} />,
Trans: ({ children }) =>
Array.isArray(children) ? renderNodes(children) : renderNodes([children]),
Translation: ({ children }) => children((k) => k, { i18n: {} }),
useTranslation: () => useMock,
// mock if needed
I18nextProvider: reactI18next.I18nextProvider,
initReactI18next: reactI18next.initReactI18next,
setDefaults: reactI18next.setDefaults,
getDefaults: reactI18next.getDefaults,
setI18n: reactI18next.setI18n,
getI18n: reactI18next.getI18n,
};
The major parte is of the documentation of i18n i only add the way to show the right traduction
https://react.i18next.com/misc/testing https://github.com/i18next/react-i18next/blob/master/example/test-jest/src/__mocks__/react-i18next.js
Upvotes: 0
Reputation: 5005
Create a file __mocks__/react-i18next.js
(the folder __mocks__
being next to node_modules
, in the same parent folder), containing:
module.exports = {
useTranslation: () => ({
t: key => key,
}),
}
In your test script, import useTranslation
normally, but define the mock to be used.
import {useTranslation} from 'react-i18next'
/* Other imports and code */
jest.mock('react-i18next')
/* Your test code using useTranslation */
Upvotes: 4
Reputation: 98
Create a mock file: __mocks__/react-i18next.useTranslation.js
with this content:
module.exports = () => {
return () => ({
t: key => key
})
}
Upvotes: 3