Open phun-ky opened 6 months ago
make sure the file that contains the i18next.init call is included/required during your tests
@adrai thanks for the suggestion. I've tried that with no avail sadly :/ Tried to include it in the test, in the test setup file, the renderWithI18NContext
wrapper and in the component I am testing.
hard to help, sorry
@phun-ky this might be due to something called "dual package hazard" https://github.com/vitest-dev/vitest/issues/3287#issuecomment-1534159966
Had a similar issue (main code was using different build of the package than the library
adding the following to vite.config.js
solved the issue for me:
resolve: {
alias: {
'react-i18next': path.resolve(__dirname, './node_modules/react-i18next/dist/commonjs/index.js'), // https://github.com/vitest-dev/vitest/issues/3287#issuecomment-1534159966
},
},
Hi @phun-ky ,
I had the same problem and I solved it by using i18next-fs-backend
in my component wrapper.
Also, to make it works, i18n instance needs to be created and initialized synchronously.
Please note the await
on init
call and the option initImmediate: false
.
import {render as rtlRender} from '@testing-library/react'
import {I18nextProvider, initReactI18next} from "react-i18next";
import {createInstance} from "i18next";
import Backend from "i18next-fs-backend";
import translation from "../public/locales/en/translation.json"
const instance = createInstance()
await instance
.use(Backend)
.use(initReactI18next)
.init({
fallbackLng: "en",
debug: false,
interpolation: {
escapeValue: false
},
defaultNS: "translation",
initImmediate: false,
resources: {
en: {
translation
}
}
});
export const render = (ui: JSX.Element) => {
function Wrapper({children}: any): any {
return (
<I18nextProvider i18n={instance}>
{children}
</I18nextProvider>
)
}
rtlRender(ui, {wrapper: Wrapper})
}
Hope that can help
Hi there,
I just found an alternative for me, which is pretty well working.
In my case I need to use the var env import.meta.env.MODE === 'test'
import frAdmin from '../public/locales/fr/admin.json'
import frErrorBoundary from '../public/locales/fr/errorBoundary.json'
import frMenu from '../public/locales/fr/menu.json'
import frNewStudy from '../public/locales/fr/studyResults.json'
import frStudyResults from '../public/locales/fr/studyResults.json'
import enAdmin from '../public/locales/en/admin.json'
import enErrorBoundary from '../public/locales/en/errorBoundary.json'
import enMenu from '../public/locales/en/menu.json'
import enNewStudy from '../public/locales/en/studyResults.json'
import enStudyResults from '../public/locales/en/studyResults.json'
i18n
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
fallbackLng: ['fr'],
...(import.meta.env.MODE === 'test' && {
resources: {
fr: { admin: frAdmin, errorBoundary: frErrorBoundary, menu: frMenu, newStudy: frNewStudy, studyResults: frStudyResults },
en: { admin: enAdmin, errorBoundary: enErrorBoundary, menu: enMenu, newStudy: enNewStudy, studyResults: enStudyResults }
}
}),
interpolation: {
escapeValue: false // not needed for react as it escapes by default
},
...(import.meta.env.MODE !== 'test' && { ns: ['menu', 'studyResults', 'newStudy', 'admin'] })
})
import { render, screen } from '@testing-library/react'
import { MyComponent } from './MyComponent'
import { I18nextProvider } from 'react-i18next'
import { setupStore } from '../../modules/store'
import { Provider } from 'react-redux'
import i18n from '../../i18n'
const store = setupStore()
test("renders all the stuff you want", () => {
render(
<Provider store={store}>
<I18nextProvider i18n={i18n}>
<MyComponent />
</I18nextProvider>
</Provider>
)
expect(screen.getByText('I am looking for my sentence here')).toBeDefined()
})
Actually by just defining the namespaces, with this line ns: ['menu', 'studyResults', 'newStudy', 'admin']
the testing library didn't open the json files, so I had to import them one by one and put them in the classical resources: { fr:{}, en:{} }
style attributes.
I have been trying your asynchronous stuff @RomRom1 but not working.
🐛 Bug Report
Language is not set during tests with
vitest
. In a dependency I import, this code exists:This code throws
throw Error('Language must be either nb or en.');
when testing usingvitest
. It does not throw for building withvite
nor with the previous test runnerjest
(with practically same config).That code is wrapping a component that is consumed by several components up until the file I am testing, which is using this:
With an import
i18n
that looks like this:Which is consumed like this:
I've narrowed it down to
react-i18next
is not picking up language, i.e., thatuse(initReactI18next).init({…})
is not called, or something..To Reproduce
I cannot produce a reproduction case due to the complexity of the internal (non public) dependencies, which I also think has something to do with this. As stated, I think this is a misconfiguration on my part, not a bug itself.
Expected behavior
That language is set.
Your Environment