2

next-i18next uses it's own Link component to be compatible with locale sub-paths.

https://github.com/isaachinman/next-i18next

When I try a simple snapshot test I get the error Cannot read property language of undefined.

My component:

import React from 'react';
import { TFunction } from 'next-i18next';
import { withTranslation, Link } from '../../../i18n';

interface HeaderProps {
  readonly t: TFunction;
}

const Header = ({ t }: HeaderProps): JSX.Element => {
  return (
    <>
      <Flex>
        <Box>
          <Link href="/">{t('home')}</Link>
        </Box>
      </Flex>
    </>
  );
};

export default withTranslation('common')(Header);

It's snapshot test:

import React from 'react';
import { render, screen } from '@testing-library/react';
import Header from './Header';

describe('<Header/>', () => {
  test('it should render correctly', () => {
    const { container } = render(<Header />);
    expect(container.firstChild).toMatchSnapshot();
  });
});

The test runs and passes without the Link component as expected.

I have defined my i18n.ts as follows:

import path from 'path';
import NextI18Next from 'next-i18next';
import { publicRuntimeConfig } from './next.config';

const { localeSubpaths } = publicRuntimeConfig;

export const nextI18next = new NextI18Next({
  browserLanguageDetection: false,
  defaultNS: 'common',
  defaultLanguage: 'en',
  fallbackLng: 'en',
  otherLanguages: ['fr'],
  localeSubpaths,
  localePath: path.resolve('./public/static/locales'),
});

export const {
  i18n,
  appWithTranslation,
  Link,
  withTranslation,
  Router,
} = nextI18next;

Is there anyway I can fix this error?

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
RyanP13
  • 7,413
  • 27
  • 96
  • 166

2 Answers2

1

You should wrap your component under test with i18nextProvider.

Check Stubbing I18next useTranslation hook in Jest doesn't trigger toHaveBeenCalled

Edit I18next has a "special" languages (cimode) which makes the t function always return the given key, this way in tests you can assert on the key instead of the value (which can be changed, sometimes not by the developer).

felixmosh
  • 32,615
  • 9
  • 69
  • 88
  • This didn't help me. Can you share more info on this `language` property? – alexp Oct 16 '20 at 07:15
  • If it matters I am on Next.js 9.5.4. – alexp Oct 16 '20 at 07:22
  • Yes, "TypeError: Cannot read property 'language' of undefined" It shows for both page components and regular React components when they have Link imported from i18n. No problem if Link is commented out, test can identify other translation keys used in the view. I would appreciate some hints on what to debug next. – alexp Oct 16 '20 at 16:14
  • Did you wrapped your Component under test with the i18nextProvider? – felixmosh Oct 16 '20 at 16:18
  • I used a custom render function (https://testing-library.com/docs/example-react-intl#creating-a-custom-render-function), tried both I18NextProvider (locale not passed as a prop) and IntlProvider (passing locale='en') with the same results. – alexp Oct 16 '20 at 16:29
  • Since your are using next-i18next, try to wrap with `withAppTranslation`, (https://github.com/isaachinman/next-i18next/blob/a538ad4b4fb9357c36b189849e351190ed138013/src/hocs/app-with-translation.tsx) – felixmosh Oct 16 '20 at 17:06
  • Already doing it. Otherwise I believe the translations would not work in browser (i.e. compiled). It's just the component in test environment that's causing troubles. – alexp Oct 16 '20 at 17:39
  • You need to do it in the test env, since you are rendering your component outside of next – felixmosh Oct 16 '20 at 18:10
  • Suddenly the test started passing after I removed "/__mocks__/react-i18next.js". Lol. I guess there was some contexts conflict. Need to understand now where the stubs are coming for useTranslation and others. Thanks for assistance! – alexp Oct 17 '20 at 03:04
0

For every one who can't get why this error is exist: check your locale files is correct and doesn't content special symbols out of quotes

nDiviD
  • 444
  • 1
  • 4
  • 11