-
-
Notifications
You must be signed in to change notification settings - Fork 761
How do you test for translations using Jest and Testing Library? #2083
Replies: 1 comment · 4 replies
-
maybe analogous to: https://react.i18next.com/misc/testing |
Beta Was this translation helpful? Give feedback.
All reactions
-
Good day, maybe you could take a look into my case? I am using [index.tsx] file
...
export const getStaticProps: GetStaticProps = async ({ locale }) => ({
props: {
...(await serverSideTranslations(locale ?? 'de', [
'common',
'header',
'footer'
]))
}
}) [_app.tsx] file
import { appWithTranslation } from 'next-i18next'
...
export default appWithTranslation(App)
[Loca.tsx] file
import React from 'react'
import { useTranslation, i18n } from 'next-i18next'
type BaseProps = {
id: string
values?: Record<string, React.ReactNode>
}
export type Props<T extends React.ElementType> = { as?: T } & Omit<
React.ComponentPropsWithRef<T>,
keyof BaseProps | 'as'
> &
BaseProps
export const Loca = <T extends React.ElementType>(props: Props<T>) => {
const { as, values, id, ...rest } = props
const i18ns = i18n?.options.ns
const { t } = useTranslation(i18ns)
const mutatedValues = { ...values }
const element = t(id, mutatedValues)
return React.createElement(as || React.Fragment, rest, element)
}
[Loca.tsx] file
import React from 'react'
import { Loca as BaseLoca, Props } from '@app/intl/component'
export const Loca = <T extends React.ElementType>(props: Props<T>) => {
return React.createElement(BaseLoca, {
...props,
as: props.as || 'span'
})
}
...
<Loca as="h1" id="common:help" values={{ value: '123' }} />
...
[jest.setup.ts] file
// Mock t function
export const t = (key: string, params?: any) => {
if (key === 'key.with.params') {
return `key.with.params.${params.param}`
}
return key
}
// Mock react-i18next
i18n.use(initReactI18next).init({
lng: 'de',
fallbackLng: 'de',
ns: ['common', 'footer', 'header'],
defaultNS: 'common',
resources: {
de: {
common: {
description:
'This is a non-page component that requires its own namespace',
help: 'With using {{ value }} <1>locize</1> you directly support the future of <3>i18next</3>.',
test: {
ta: 'ta ta ta {{value}}'
}
}
}
}
})
// Mock your i18n
jest.mock('next-i18next', () => {
return {
useTranslation: () => {
return {
t,
i18n: {
language: 'de',
changeLanguage: jest
.fn()
.mockImplementation((lang: string) => console.log(lang))
}
}
},
withTranslation: () => (Component: any) => {
Component.defaultProps = { ...Component.defaultProps, t }
return Component
}
}
}) export const wrapper = ({ mock }: Props) => {
const router = mockRouter(mock)
const App = ({ children }: Props) => (
<RouterContext.Provider value={router}>
<UI />
<StartPage />
{children}
</RouterContext.Provider>
)
return {
App,
router
}
} [ui.test.tsx] file
...
const { App, router } = wrapper({})
...
it('to load i18', async () => {
await act(async () => void render(<App />))
const response = await getStaticProps('de' as GetStaticPropsContext)
expect(response).toEqual(expect.objectContaining(i18props))
const text = await screen.findByText('common:helps')
expect(text).toMatchSnapshot()
}) {
"description": "This is a non-page component that requires its own namespace",
"help": "With using {{ value }} <1>locize</1> you directly support the future of <3>i18next</3>.",
"test": {
"ta": "ta ta ta {{value}}"
}
} Intentional error |
Beta Was this translation helpful? Give feedback.
All reactions
-
Okay, that was weird - maybe also could be explained why it worked in my case? in import '@testing-library/jest-dom/extend-expect'
import i18next from 'i18next'
import { initReactI18next } from 'react-i18next'
import common from '../../bahag-app/src/__tests__/locale/de/common.json'
import footer from '../../bahag-app/src/__tests__/locale/de/footer.json'
import header from '../../bahag-app/src/__tests__/locale/de/header.json'
...
i18next.use(initReactI18next).init({
lng: 'de',
fallbackLng: 'de',
ns: ['common', 'footer', 'header'],
defaultNS: 'common'
})
i18next.addResources('de', 'common', common)
i18next.addResources('de', 'footer', header)
i18next.addResources('de', 'header', footer) And I am not using |
Beta Was this translation helpful? Give feedback.
All reactions
-
Thanks a lot for a lot of details. But still couldn't understand what result did you achieve - are you successfully rendering the actual value of the translation or? |
Beta Was this translation helpful? Give feedback.
All reactions
-
Thanks for the reply! Ye, I am successfully rendering the "help": "With using {{ value }} you directly support the future of .", I have made an intentional error so that I could show that the key is not being rendered into the content/text. So instead of [ui.test.tsx] file
it('to load i18', async () => {
await act(async () => void render(<App />))
const response = await getStaticProps('de' as GetStaticPropsContext)
expect(response).toEqual(expect.objectContaining(i18props))
const textCommon = await screen.findByText(/footer/i)
const textFooter = await screen.findByText(/header/i)
const textHeader = await screen.findByText(/with using/i)
expect(textCommon).toBeInTheDocument()
expect(textFooter).toBeInTheDocument()
expect(textHeader).toBeInTheDocument()
}) |
Beta Was this translation helpful? Give feedback.
-
Hi,
I wanted to know how I can test for actual translations using Jest and Testing Library. In my components, I am using the
useTranslation()
fromnext-i18next
like so.const { t } = useTranslation('<namespace>');
const text = t('<key>, { ns: '<namespace>', defaultValue: '<defaultValue> });
When rendering the component using Testing Library, only the key name appears in the component. How can I test so the component renders actual content and not the key name?
Thanks
Beta Was this translation helpful? Give feedback.
All reactions