-1

I have used latest version of React-intl(^5.20.2). Trying to achieve Enzyme Unit testing in React hook component. but throwing this error "[React Intl] Could not find required intl object. needs to exist in the component ancestry." on UseIntl() inside functional component while running tests

{intl.formatMessage({ id: "Welcome" })}

Vindhiya
  • 1
  • 1
  • 1

2 Answers2

1

You need to wrap the component under test with the IntlProvider component. You can do this by creating a wrapper to pass in the options with the render utility.

Wrapper

Pass a React Component as the wrapper option to have it rendered around the inner element. This is most useful for creating reusable custom render functions for common data providers.

Example:

import { IntlProvider } from 'react-intl';

export const IntlWrapper = ({ children }) => (
  <IntlProvider locale="en">{children}</IntlProvider>
);

Test code

import { render } from '@testing-library/react';
import { IntlWrapper } from '../path/to/testUtils';

...

render(
  <ComponentUnderTest />,
  {
    wrapper: IntlWrapper,
  },
);
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • "No overload matches this call. Overload 1 of 2, '(ui: ReactElement>, options: RenderOptions" is throwing while using wrapper after component – Vindhiya Aug 23 '21 at 07:31
  • @Vindhiya It should work, but you can also just directly wrap the component being tested with the `IntlProvider` component too. – Drew Reese Aug 23 '21 at 07:35
0

Okay so in my case it was due to SSR.

In addition of the "locale" Provider which allow language switching.

I've added to my _document.jsx a Provider which get the locale from the router.

class MyDocument extends Document<TDocumentInitialProps> {
    static async getInitialProps(ctx: DocumentContext): Promise<TDocumentInitialProps> {
        const messages = (await importMessages(ctx.locale)) as Record<string, string> | Record<string, MessageFormatElement[]>;

        return {
            locale: ctx.locale,
            messages,
        };
    }

    render(): JSX.Element {
        const { locale, messages } = this.props;

        return (
        <IntlProvider locale={locale} messages={messages}>
            <Html lang={locale}>
            <Head>
                <link rel="icon" href="/images/layout/favicon.png" />
            </Head>
            <body>
                <Main />
                <NextScript />
            </body>
            </Html>
        </IntlProvider>
        );
    }
}

export default MyDocument;
Baldráni
  • 5,332
  • 7
  • 51
  • 79